namespace Reflector.Languages
{
    using Reflector;
    using Reflector.CodeModel;
    using System;
    using System.Collections;
    using System.Globalization;
    using System.IO;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;

    public class CppCliLanguage : ILanguage
    {
        public virtual ILanguageWriter GetWriter(IFormatter formatter, ILanguageWriterConfiguration configuration)
        {
            return new LanguageWriter(formatter, configuration);
        }

        public virtual string FileExtension
        {
            get
            {
                return ".cpp";
            }
        }

        public virtual string Name
        {
            get
            {
                return "C++/CLI";
            }
        }

        public virtual bool Translate
        {
            [return: MarshalAs(UnmanagedType.U1)]
            get
            {
                return true;
            }
        }

        public class LanguageWriter : Helper, ILanguageWriter
        {
            private ITypeReference baseType;
            private int Block;
            private ILanguageWriterConfiguration configuration;
            private bool[] EssentialTemporaries;
            private string[] ExtraMappings;
            private string[] ExtraTemporaries;
            private IFormatter formatter;
            private int NextBlock;
            public Hashtable refOnStack;
            private int SkipNullptrCount;
            private int SkipTryCount;
            private bool SkipWriteLine;
            private bool SomeConstructor;
            public static Hashtable specialMethodNames;
            public static Hashtable specialTypeNames = new Hashtable();
            private bool SuppressOutput;
            private int[] TemporaryBlocks;

            static LanguageWriter()
            {
                specialTypeNames["Void"] = "void";
                specialTypeNames["Boolean"] = "bool";
                specialTypeNames["Char"] = "wchar_t";
                specialTypeNames["SByte"] = "char";
                specialTypeNames["Byte"] = "unsigned char";
                specialTypeNames["Int16"] = "short";
                specialTypeNames["UInt16"] = "unsigned short";
                specialTypeNames["Int32"] = "int";
                specialTypeNames["UInt32"] = "unsigned int";
                specialTypeNames["Int64"] = "long long";
                specialTypeNames["UInt64"] = "unsigned long long";
                specialTypeNames["Single"] = "float";
                specialTypeNames["Double"] = "double";
                specialMethodNames = new Hashtable();
                specialMethodNames["op_AddressOf"] = "operator & ";
                specialMethodNames["op_LogicalNot"] = "operator ! ";
                specialMethodNames["op_OnesComplement"] = "operator ~ ";
                specialMethodNames["op_PointerDereference"] = "operator * ";
                specialMethodNames["op_UnaryNegation"] = "operator - ";
                specialMethodNames["op_UnaryPlus"] = "operator + ";
                specialMethodNames["op_MemberSelection"] = "operator -> ";
                specialMethodNames["op_Addition"] = "operator + ";
                specialMethodNames["op_BitwiseAnd"] = "operator & ";
                specialMethodNames["op_BitwiseOr"] = "operator | ";
                specialMethodNames["op_ExclusiveOr"] = "operator ^ ";
                specialMethodNames["op_Increment"] = "operator ++ ";
                specialMethodNames["op_Subtraction"] = "operator - ";
                specialMethodNames["op_Decrement"] = "operator -- ";
                specialMethodNames["op_Multiply"] = "operator * ";
                specialMethodNames["op_Division"] = "operator / ";
                specialMethodNames["op_Modulus"] = "operator % ";
                specialMethodNames["op_Negation"] = "operator ! ";
                specialMethodNames["op_LeftShift"] = "operator << ";
                specialMethodNames["op_RightShift"] = "operator >> ";
                specialMethodNames["op_Equality"] = "operator == ";
                specialMethodNames["op_Inequality"] = "operator != ";
                specialMethodNames["op_GreaterThanOrEqual"] = "operator >= ";
                specialMethodNames["op_LessThanOrEqual"] = "operator <= ";
                specialMethodNames["op_GreaterThan"] = "operator > ";
                specialMethodNames["op_LessThan"] = "operator < ";
                specialMethodNames["op_True"] = "operator true ";
                specialMethodNames["op_False"] = "operator false ";
                specialMethodNames["op_Implicit"] = "implicit ";
                specialMethodNames["op_Explicit"] = "explicit ";
            }

            public LanguageWriter(IFormatter formatter, ILanguageWriterConfiguration configuration)
            {
                this.formatter = formatter;
                this.configuration = configuration;
            }

            [return: MarshalAs(UnmanagedType.U1)]
            private bool BlankStatement(IStatement iStatement)
            {
                if (iStatement == null)
                {
                    return true;
                }
                IBlockStatement statement = iStatement as IBlockStatement;
                if (statement != null)
                {
                    IStatementCollection statements = statement.Statements;
                    if (statements != null)
                    {
                        return (statements.Count == 0);
                    }
                }
                return false;
            }

            private int GatherExtraTemporaries(IStatementCollection iStatementCollection)
            {
                if (this.ExtraTemporaries != null)
                {
                    goto Label_00CF;
                }
                int num2 = 0;
            Label_0013:
                if (num2 >= 2)
                {
                    goto Label_00CF;
                }
                int index = 0;
            Label_0022:
                if (index < iStatementCollection.Count)
                {
                    IStatement statement = iStatementCollection[index];
                    IAssignExpression expression = statement as IAssignExpression;
                    if (expression != null)
                    {
                        ILiteralExpression expression3 = expression.Expression as ILiteralExpression;
                        if ((expression3 != null) && (expression3.Value == null))
                        {
                            IVariableDeclarationExpression target = expression.Target as IVariableDeclarationExpression;
                            if (target != null)
                            {
                                if (num2 == 1)
                                {
                                    this.ExtraTemporaries[index] = target.Variable.Name;
                                }
                                index++;
                                goto Label_0022;
                            }
                        }
                    }
                }
                if (num2 == 0)
                {
                    this.SkipNullptrCount = index;
                    this.ExtraTemporaries = new string[index];
                    this.ExtraMappings = new string[this.SkipNullptrCount];
                    this.EssentialTemporaries = new bool[this.SkipNullptrCount];
                    this.TemporaryBlocks = new int[this.SkipNullptrCount];
                }
                num2++;
                goto Label_0013;
            Label_00CF:
                return this.SkipNullptrCount;
            }

            private string GetCustomAttributeName(ICustomAttribute iCustomAttribute)
            {
                ITypeReference declaringType = iCustomAttribute.Constructor.DeclaringType as ITypeReference;
                string nameFromTypeReference = this.GetNameFromTypeReference(declaringType);
                if (nameFromTypeReference.EndsWith("Attribute"))
                {
                    nameFromTypeReference = nameFromTypeReference.Substring(0, nameFromTypeReference.Length - 9);
                }
                return nameFromTypeReference;
            }

            public virtual string GetNameFromType(IType iType)
            {
                IOptionalModifier modifier = iType as IOptionalModifier;
                if (modifier != null)
                {
                    string nameFromType = this.GetNameFromType(modifier.ElementType);
                    if (0 != 0)
                    {
                        if (nameFromType == "int")
                        {
                            nameFromType = "long";
                        }
                        return nameFromType;
                    }
                    return (nameFromType + (" " + modifier.Modifier.ToString()));
                }
                ITypeReference typeReference = iType as ITypeReference;
                if (typeReference != null)
                {
                    return this.GetNameFromTypeReference(typeReference);
                }
                return iType.ToString();
            }

            private string GetNameFromTypeReference(ITypeReference typeReference)
            {
                string name = typeReference.Name;
                if ((typeReference.Namespace == "System") && specialTypeNames.Contains(name))
                {
                    name = (string) specialTypeNames[name];
                }
                ITypeCollection genericArguments = typeReference.GenericArguments;
                if (genericArguments.Count > 0)
                {
                    string str2 = "";
                    name = name + "<";
                    foreach (IType type in genericArguments)
                    {
                        name = name + str2;
                        str2 = ",";
                        name = name + this.GetNameFromType(type);
                    }
                    name = name + ">";
                }
                return name.Replace(".", "::").Replace("+", "::");
            }

            private string GetVariableName(IExpression iExpression)
            {
                IVariableDeclarationExpression expression2 = iExpression as IVariableDeclarationExpression;
                if (expression2 != null)
                {
                    return expression2.Variable.Name;
                }
                IVariableReferenceExpression expression = iExpression as IVariableReferenceExpression;
                if (expression != null)
                {
                    return expression.Variable.Resolve().Name;
                }
                return null;
            }

            private string MapTemporaryName(string s)
            {
                if (this.ExtraTemporaries != null)
                {
                    for (int i = 0; i < this.ExtraTemporaries.Length; i++)
                    {
                        if ((!this.EssentialTemporaries[i] && (s == this.ExtraTemporaries[i])) && this.VerifyCorrectBlock(i))
                        {
                            if (this.ExtraMappings[i] != null)
                            {
                                return this.ExtraMappings[i];
                            }
                            this.EssentialTemporaries[i] = true;
                            return "mapping error";
                        }
                    }
                }
                return s;
            }

            private void NotAReference(string Name)
            {
                this.refOnStack[Name] = Name;
            }

            [return: MarshalAs(UnmanagedType.U1)]
            private bool Type(IType type, string typeNamespace, string typeName)
            {
                ITypeReference reference = type as ITypeReference;
                if (reference != null)
                {
                    int num;
                    if ((reference.Namespace == typeNamespace) && (reference.Name == typeName))
                    {
                        num = 1;
                    }
                    else
                    {
                        num = 0;
                    }
                    return (bool) (num != 0);
                }
                return false;
            }

            public override void TypeWriter(StringWriter writer, IType iType)
            {
                writer.Write(this.GetNameFromType(iType));
            }

            [return: MarshalAs(UnmanagedType.U1)]
            private bool VerifyCorrectBlock(int i)
            {
                if (this.SuppressOutput)
                {
                    if (this.TemporaryBlocks[i] == 0)
                    {
                        this.TemporaryBlocks[i] = this.Block;
                    }
                    else if (this.TemporaryBlocks[i] != this.Block)
                    {
                        this.EssentialTemporaries[i] = true;
                        return false;
                    }
                }
                return true;
            }

            private void Write(string s)
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.Write(s);
                }
            }

            private void WriteAddressDereferenceExpression(IAddressDereferenceExpression expression)
            {
                this.Write("*(");
                this.WriteExpression(expression.Expression);
                this.Write(")");
            }

            private void WriteAddressOfExpression(IAddressOfExpression expression)
            {
                this.Write("&");
                this.WriteExpression(expression.Expression);
            }

            private void WriteAddressOutExpression(IAddressOutExpression expression)
            {
                this.WriteExpression(expression.Expression);
            }

            private void WriteAddressReferenceExpression(IAddressReferenceExpression expression)
            {
                this.WriteExpression(expression.Expression);
            }

            private void WriteArgumentListExpression(IArgumentListExpression expression)
            {
                this.WriteKeyword("__arglist");
            }

            private void WriteArgumentReferenceExpression(IArgumentReferenceExpression expression1)
            {
                this.WriteReference(expression1.Parameter.Name, "", expression1.Parameter);
            }

            private void WriteArrayCreateExpression(IArrayCreateExpression expression1)
            {
                IBlockExpression initializer = expression1.Initializer;
                if (initializer != null)
                {
                    this.WriteBlockExpression(initializer);
                }
                else
                {
                    this.WriteKeyword("gcnew");
                    this.Write(" ");
                    this.Write("array<");
                    this.WriteType(expression1.Type, null, null, null, false);
                    if (expression1.Dimensions.Count > 1)
                    {
                        this.Write(", " + expression1.Dimensions.Count.ToString());
                    }
                    this.Write(">");
                    this.Write("(");
                    this.WriteExpressionCollection(expression1.Dimensions);
                    this.Write(")");
                }
            }

            private void WriteArrayIndexerExpression(IArrayIndexerExpression expression)
            {
                this.WriteExpression(expression.Target);
                this.Write("[");
                string s = "";
                foreach (IExpression expression2 in expression.Indices)
                {
                    this.Write(s);
                    this.WriteExpression(expression2);
                    s = ",";
                }
                this.Write("]");
            }

            public virtual void WriteAssembly(IAssembly assembly)
            {
                this.Write("// Assembly");
                this.Write(" ");
                this.WriteDeclaration(assembly.Name);
                if (assembly.Version != null)
                {
                    this.Write(", ");
                    this.Write("Version");
                    this.Write(" ");
                    this.Write(assembly.Version.ToString());
                }
                this.WriteLine();
                if ((this.configuration["ShowCustomAttributes"] == "true") && (assembly.Attributes.Count != 0))
                {
                    this.WriteLine();
                    this.WriteLine();
                }
                this.WriteProperty("Location", assembly.Location);
                this.WriteProperty("Name", assembly.ToString());
            }

            public virtual void WriteAssemblyReference(IAssemblyReference assemblyReference)
            {
                this.Write("// Assembly Reference");
                this.Write(" ");
                this.WriteDeclaration(assemblyReference.Name);
                this.WriteLine();
                this.WriteProperty("Version", assemblyReference.Version.ToString());
                this.WriteProperty("Name", assemblyReference.ToString());
            }

            private void WriteAssignExpression(IAssignExpression iAssignExpression)
            {
                IVariableDeclarationExpression target = iAssignExpression.Target as IVariableDeclarationExpression;
                IVariableReferenceExpression expression2 = iAssignExpression.Target as IVariableReferenceExpression;
                IVariableReferenceExpression expression = iAssignExpression.Expression as IVariableReferenceExpression;
                if (this.ExtraTemporaries != null)
                {
                    for (int i = 0; i < this.ExtraTemporaries.Length; i++)
                    {
                        if ((!this.EssentialTemporaries[i] && (target != null)) && (target.Variable.Name == this.ExtraTemporaries[i]))
                        {
                            return;
                        }
                    }
                    if ((expression2 != null) && (expression != null))
                    {
                        int index = -1;
                        int num2 = -1;
                        for (int j = 0; j < this.ExtraTemporaries.Length; j++)
                        {
                            if (expression2.Variable.ToString() == this.ExtraTemporaries[j])
                            {
                                index = j;
                                this.VerifyCorrectBlock(j);
                            }
                            if (expression.Variable.ToString() == this.ExtraTemporaries[j])
                            {
                                num2 = j;
                                this.VerifyCorrectBlock(j);
                            }
                        }
                        if ((index >= 0) && !this.EssentialTemporaries[index])
                        {
                            string str;
                            if ((num2 >= 0) && !this.EssentialTemporaries[num2])
                            {
                                if (this.ExtraMappings[num2] == null)
                                {
                                    this.EssentialTemporaries[num2] = true;
                                    str = null;
                                }
                                else
                                {
                                    str = this.ExtraMappings[num2];
                                }
                            }
                            else
                            {
                                str = expression.Variable.ToString();
                            }
                            if ((str != null) && (expression2.Variable.ToString()[0] == str[0]))
                            {
                                this.ExtraMappings[index] = str;
                                return;
                            }
                        }
                    }
                }
                this.WriteExpression(iAssignExpression.Target);
                this.Write(" = ");
                this.WriteExpression(iAssignExpression.Expression);
            }

            private void WriteAttachEventStatement(IAttachEventStatement iAttachEventStatement)
            {
                this.WriteEventReferenceExpression(iAttachEventStatement.Event);
                this.Write(" += ");
                this.WriteExpression(iAttachEventStatement.Listener);
                this.Write(";");
                this.WriteLine();
            }

            private void WriteBaseReferenceExpression(IBaseReferenceExpression iBaseReferenceExpression)
            {
                this.WriteTypeReference(this.baseType);
            }

            private void WriteBinaryExpression(IBinaryExpression iBinaryExpression)
            {
                this.Write("(");
                this.WriteExpression(iBinaryExpression.Left);
                this.Write(" ");
                this.WriteBinaryOperator(iBinaryExpression.Operator);
                this.Write(" ");
                this.WriteExpression(iBinaryExpression.Right);
                this.Write(")");
            }

            private void WriteBinaryOperator( BinaryOperator binaryOperator)
            {
                switch (((BinaryOperator) binaryOperator))
                {
                    case BinaryOperator.Add:
                        this.Write("+");
                        break;

                    case BinaryOperator.Subtract:
                        this.Write("-");
                        break;

                    case BinaryOperator.Multiply:
                        this.Write("*");
                        break;

                    case BinaryOperator.Divide:
                        this.Write("/");
                        break;

                    case BinaryOperator.Modulus:
                        this.Write("%");
                        break;

                    case BinaryOperator.ShiftLeft:
                        this.Write("<<");
                        break;

                    case BinaryOperator.ShiftRight:
                        this.Write(">>");
                        break;

                    case BinaryOperator.IdentityEquality:
                        this.Write("==");
                        break;

                    case BinaryOperator.IdentityInequality:
                        this.Write("!=");
                        break;

                    case BinaryOperator.ValueEquality:
                        this.Write("==");
                        break;

                    case BinaryOperator.ValueInequality:
                        this.Write("!=");
                        break;

                    case BinaryOperator.BitwiseOr:
                        this.Write("|");
                        break;

                    case BinaryOperator.BitwiseAnd:
                        this.Write("&");
                        break;

                    case BinaryOperator.BitwiseExclusiveOr:
                        this.Write("^");
                        break;

                    case BinaryOperator.BooleanOr:
                        this.Write("||");
                        break;

                    case BinaryOperator.BooleanAnd:
                        this.Write("&&");
                        break;

                    case BinaryOperator.LessThan:
                        this.Write("<");
                        break;

                    case BinaryOperator.LessThanOrEqual:
                        this.Write("<=");
                        break;

                    case BinaryOperator.GreaterThan:
                        this.Write(">");
                        break;

                    case BinaryOperator.GreaterThanOrEqual:
                        this.Write(">=");
                        break;

                    default:
                        throw new NotSupportedException(binaryOperator.ToString());
                }
            }

            private void WriteBlockExpression(IBlockExpression expression1)
            {
                this.Write("{");
                this.WriteExpressionCollection(expression1.Expressions);
                this.Write("}");
            }

            private void WriteBlockStatement(IBlockStatement blockStatement)
            {
                if (blockStatement.Statements.Count > 0)
                {
                    this.WriteStatementCollection(blockStatement.Statements, 0);
                }
            }

            private void WriteBreakStatement(IBreakStatement iBreakStatement)
            {
                this.WriteKeyword("break");
                this.Write(";");
                this.WriteLine();
            }

            private void WriteCanCastExpression(ICanCastExpression iCanCastExpression)
            {
                this.Write("(");
                this.WriteKeyword("dynamic_cast");
                this.Write("<");
                this.WriteType(iCanCastExpression.TargetType, null, null, null, false);
                this.Write(">");
                this.Write("(");
                this.WriteExpression(iCanCastExpression.Expression);
                this.Write(")");
                this.Write(" != nullptr");
                this.Write(")");
            }

            private void WriteCastExpression(ICastExpression iCastExpression)
            {
                this.Write("((");
                this.WriteType(iCastExpression.TargetType, null, null, null, false);
                this.Write(") ");
                this.WriteExpression(iCastExpression.Expression);
                this.Write(")");
            }

            private void WriteClassDeclaration(ITypeDeclaration typeDeclaration)
            {
                this.WriteTypeVisibilitySpecifier(typeDeclaration.Visibility);
                bool flag2 = false;
                bool flag = false;
                this.WriteGenericArguments(typeDeclaration.GenericArguments);
                if (base.IsValueType(typeDeclaration))
                {
                    this.WriteKeyword("value");
                    this.Write(" ");
                    this.WriteKeyword("class");
                    flag2 = true;
                }
                else if (typeDeclaration.Interface)
                {
                    this.WriteKeyword("interface");
                    this.Write(" ");
                    this.WriteKeyword("class");
                    flag = true;
                }
                else
                {
                    this.WriteKeyword("ref");
                    this.Write(" ");
                    this.WriteKeyword("class");
                }
                this.Write(" ");
                this.Write(typeDeclaration.Name);
                if (typeDeclaration.Abstract && !flag)
                {
                    this.Write(" ");
                    this.WriteKeyword("abstract");
                }
                if (typeDeclaration.Sealed && !flag2)
                {
                    this.Write(" ");
                    this.WriteKeyword("sealed");
                }
                string s = " : ";
                if (((typeDeclaration.BaseType != null) && !base.IsObject(typeDeclaration.BaseType)) && !base.IsValueType(typeDeclaration.BaseType))
                {
                    this.Write(s);
                    this.WriteKeyword("public");
                    this.Write(" ");
                    this.WriteTypeReference(typeDeclaration.BaseType);
                    s = ", ";
                }
                foreach (ITypeReference reference in typeDeclaration.Interfaces)
                {
                    this.Write(s);
                    this.WriteKeyword("public");
                    this.Write(" ");
                    this.WriteTypeReference(reference);
                    s = ", ";
                }
                this.WriteLine();
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                
                if (this.configuration["ShowTypeDeclarationBody"] == "true")
                {
                    ICollection nestedTypes = base.GetNestedTypes(typeDeclaration, this.configuration.Visibility);
                    if (nestedTypes.Count > 0)
                    {
                        this.WriteComment("// Nested types");
                        this.WriteLine();
                        foreach (ITypeDeclaration declaration5 in nestedTypes)
                        {
                            this.WriteTypeDeclaration(declaration5);
                            this.WriteLine();
                        }
                    }
                   
                    ICollection methods = base.GetMethods(typeDeclaration, this.configuration.Visibility);
                    if (methods.Count > 0)
                    {
                        this.WriteComment("// Methods");
                        this.WriteLine();
                        foreach (IMethodDeclaration declaration4 in methods)
                        {
                            this.WriteMethodDeclaration(declaration4);
                            this.WriteLine();
                        }
                    }
                   
                    ICollection fields = base.GetFields(typeDeclaration, this.configuration.Visibility);         
                    if (fields.Count > 0)
                    {
                        this.WriteComment("// Fields");
                        this.WriteLine();
                        foreach (IFieldDeclaration declaration3 in fields)
                        {
                            this.WriteFieldDeclaration(declaration3);
                            this.WriteLine();
                        }
                    }
                   
                    ICollection properties = base.GetProperties(typeDeclaration, this.configuration.Visibility);
                    if (properties.Count > 0)
                    {
                        this.WriteComment("// Properties");
                        this.WriteLine();
                        foreach (IPropertyDeclaration declaration2 in properties)
                        {
                            this.WritePropertyDeclaration(declaration2);
                            this.WriteLine();
                        }
                    }
                  
                    ICollection events = base.GetEvents(typeDeclaration, this.configuration.Visibility);
                    if (events.Count > 0)
                    {
                        this.WriteComment("// Events");
                        this.WriteLine();
                        foreach (IEventDeclaration declaration in events)
                        {
                            this.WriteEventDeclaration(declaration);
                            this.WriteLine();
                        }
                    }
                }

                this.WriteOutdent();
                this.Write("};");
                this.WriteLine();
            }

            private void WriteComment(string s)
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.WriteComment(s);
                }
            }

            private void WriteConditionExpression(IConditionExpression expression1)
            {
                this.Write("(");
                this.WriteExpression(expression1.Condition);
                this.Write(" ? ");
                this.WriteExpression(expression1.Then);
                this.Write(" : ");
                this.WriteExpression(expression1.Else);
                this.Write(")");
            }

            private void WriteConditionStatement(IConditionStatement iConditionStatement)
            {
                NewBlock block3 = null;
                NewBlock block6 = new NewBlock(this);
                try
                {
                    NewBlock block2 = null;
                    block3 = block6;
                    this.WriteKeyword("if");
                    this.Write(" ");
                    this.Write("(");
                    this.WriteExpression(iConditionStatement.Condition);
                    this.Write(")");
                    this.WriteLine();
                    NewBlock block5 = new NewBlock(this);
                    try
                    {
                        block2 = block5;
                        this.WriteExtendedStatement(iConditionStatement.Then);
                        if (!this.BlankStatement(iConditionStatement.Else))
                        {
                            NewBlock block = null;
                            NewBlock  block4 = new NewBlock(this);
                            try
                            {
                                block = block4;
                                this.WriteKeyword("else");
                                this.WriteLine();
                                this.WriteExtendedStatement(iConditionStatement.Else);
                            }
                            finally
                            {
                                block.Dispose();
                            }
                            block.Dispose();
                        }
                    }
                    finally
                    {
                        block2.Dispose();
                    }
                    block2.Dispose();
                }
                finally
                {
                    block3.Dispose();
                }
                block3.Dispose();
            }

            private void WriteContinueStatement(IContinueStatement iContinueStatement)
            {
                this.WriteKeyword("continue");
                this.Write(";");
                this.WriteLine();
            }

            private void WriteCustomAttribute(ICustomAttribute customAttribute)
            {
                string customAttributeName = this.GetCustomAttributeName(customAttribute);
                this.WriteReference(customAttributeName, "", customAttribute.Constructor);
                IExpressionCollection arguments = customAttribute.Arguments;
                if (arguments.Count != 0)
                {
                    string s = "(";
                    foreach (IExpression expression in arguments)
                    {
                        this.Write(s);
                        this.WriteExpression(expression);
                        s = ", ";
                    }
                    this.Write(")");
                }
            }

            private void WriteCustomAttributeCollection(ICustomAttributeProvider provider, IType type)
            {
                if (((this.configuration["ShowCustomAttributes"] == "true") && (provider != null)) && (provider.Attributes.Count != 0))
                {
                    ArrayList list = new ArrayList();
                    list.AddRange(provider.Attributes);
                    bool flag = false;
                    string s = null;
                    if (provider is IAssembly)
                    {
                        s = "assembly:";
                    }
                    if (provider is IModule)
                    {
                        s = "module:";
                    }
                    if (provider is IMethodReturnType)
                    {
                        s = "returnvalue:";
                    }
                    for (int i = list.Count - 1; i >= 0; i--)
                    {
                        ICustomAttribute iCustomAttribute = list[i] as ICustomAttribute;
                        if (iCustomAttribute != null)
                        {
                            switch (this.GetCustomAttributeName(iCustomAttribute))
                            {
                                case "System::ParamArray":
                                    flag = true;
                                    list.RemoveAt(i);
                                    break;

                                case "System::Runtime::InteropServices::MarshalAs":
                                {
                                    IExpressionCollection arguments = iCustomAttribute.Arguments;
                                    if (arguments != null)
                                    {
                                        IFieldReferenceExpression expression = arguments[0] as IFieldReferenceExpression;
                                        if (expression != null)
                                        {
                                            ITypeReferenceExpression target = expression.Target as ITypeReferenceExpression;
                                            if ((target != null) && (target.Type.Name == "UnmanagedType"))
                                            {
                                                IFieldReference field = expression.Field;
                                                if (field.Name == "U1")
                                                {
                                                    if (this.Type(type, "System", "Boolean"))
                                                    {
                                                        list.RemoveAt(i);
                                                    }
                                                }
                                                else if ((field.Name == "U2") && this.Type(type, "System", "Char"))
                                                {
                                                    list.RemoveAt(i);
                                                }
                                            }
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    if (flag)
                    {
                        this.Write("...");
                    }
                    if (s != null)
                    {
                        foreach (ICustomAttribute attribute3 in list)
                        {
                            this.Write("[");
                            this.WriteKeyword(s);
                            this.Write(" ");
                            this.WriteCustomAttribute(attribute3);
                            this.Write("]");
                            this.WriteLine();
                        }
                    }
                    else if (list.Count != 0)
                    {
                        string str2 = "[";
                        foreach (ICustomAttribute attribute2 in list)
                        {
                            this.Write(str2);
                            this.WriteCustomAttribute(attribute2);
                            str2 = ",";
                        }
                        this.Write("]");
                    }
                }
            }

            private void WriteDeclaration(string s)
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.WriteDeclaration(s);
                }
            }

            private void WriteDelegateCreateExpression(IDelegateCreateExpression iDelegateCreateExpression)
            {
                this.Write("(IDelegateCreateExpression NYI)");
            }

            private void WriteDelegateDeclaration(ITypeDeclaration typeDeclaration)
            {
                this.WriteGenericArguments(typeDeclaration.GenericArguments);
                this.WriteTypeVisibilitySpecifier(typeDeclaration.Visibility);
                this.WriteKeyword("delegate");
                this.Write(" ");
                IMethodDeclaration method = base.GetMethod(typeDeclaration, "Invoke");
                this.WriteType(method.ReturnType.Type, new WriteTypeMiddleCallback(WriteDelegateDeclMiddle), new DelegateDeclMiddleInfo(typeDeclaration, method), null, false);
                this.Write(";");
                this.WriteLine();
            }

            private void WriteDelegateDeclMiddle(object delegateDecl)
            {
                DelegateDeclMiddleInfo info = delegateDecl as DelegateDeclMiddleInfo;
                this.Write(info.delegateDecl.Name);
                this.WriteMethodParameterCollection(info.invokeDecl.Parameters);
            }

            private void WriteDoStatement(IDoStatement iDoStatement)
            {
                this.WriteKeyword("do");
                this.WriteLine();
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                if (iDoStatement.Body != null)
                {
                    this.WriteStatement(iDoStatement.Body);
                }
                this.WriteOutdent();
                this.Write("}");
                this.WriteLine();
                this.WriteKeyword("while");
                this.Write("(");
                if (iDoStatement.Condition != null)
                {
                    this.SkipWriteLine = true;
                    this.WriteExpression(iDoStatement.Condition);
                    this.SkipWriteLine = false;
                }
                this.Write(")");
                this.Write(";");
                this.WriteLine();
            }

            private void WriteEnumDeclaration(ITypeDeclaration typeDeclaration)
            {
                this.WriteTypeVisibilitySpecifier(typeDeclaration.Visibility);
                this.WriteKeyword("value");
                this.Write(" ");
                this.WriteKeyword("enum");
                this.Write(" ");
                this.Write(typeDeclaration.Name);
                if (this.configuration["ShowTypeDeclarationBody"] == "true")
                {
                    ArrayList list = new ArrayList();
                    foreach (IFieldDeclaration declaration in base.GetFields(typeDeclaration, this.configuration.Visibility))
                    {
                        if (declaration.SpecialName && (declaration.Name == "value__"))
                        {
                            IType fieldType = declaration.FieldType;
                            if (!this.Type(fieldType, "System", "Int32"))
                            {
                                ITypeReference typeReference = fieldType as ITypeReference;
                                this.Write(" : ");
                                this.WriteTypeReference(typeReference);
                            }
                        }
                        else
                        {
                            list.Add(declaration);
                        }
                    }
                    this.WriteLine();
                    this.Write("{");
                    this.WriteLine();
                    this.WriteIndent();
                    if (this.configuration["SortAlphabetically"] == "true")
                    {
                        list.Sort();
                    }
                    this.WriteComment("// Enumerators");
                    foreach (IFieldDeclaration declaration2 in list)
                    {
                        this.WriteLine();
                        this.WriteDeclaration(declaration2.Name);
                        this.Write(" = ");
                        this.WriteExpression(declaration2.Initializer);
                        this.Write(",");
                    }
                    this.WriteOutdent();
                    this.WriteLine();
                    this.Write("};");
                    this.WriteLine();
                }
            }

            public virtual void WriteEventDeclaration(IEventDeclaration eventDeclaration)
            {
                this.WriteKeyword("event (NYI)");
                this.Write(";");
            }

            private void WriteEventReference(IEventReference iEventReference)
            {
                this.Write(iEventReference.Name);
            }

            private void WriteEventReferenceExpression(IEventReferenceExpression iEventReferenceExpression)
            {
                if (iEventReferenceExpression.Target != null)
                {
                    ITypeReferenceExpression target = iEventReferenceExpression.Target as ITypeReferenceExpression;
                    if (target != null)
                    {
                        this.WriteTypeReferenceExpression(target);
                        this.Write("::");
                    }
                    else
                    {
                        this.WriteExpression(iEventReferenceExpression.Target);
                        IVariableReferenceExpression expression = iEventReferenceExpression.Target as IVariableReferenceExpression;
                        if (expression != null)
                        {
                            IVariableReference variable = expression.Variable;
                            if (variable != null)
                            {
                                IVariableDeclaration declaration = variable.Resolve();
                                if (declaration != null)
                                {
                                    ITypeReference variableType = declaration.VariableType as ITypeReference;
                                    if (base.IsValueType(variableType))
                                    {
                                        this.Write(".");
                                    }
                                    else
                                    {
                                        this.Write("->");
                                    }
                                }
                            }
                        }
                        else
                        {
                            this.Write("->");
                        }
                    }
                }
            }

            public virtual void WriteExpression(IExpression expression)
            {
                if (expression != null)
                {
                    IPropertyIndexerExpression iPropertyIndexerExpression = expression as IPropertyIndexerExpression;
                    if (iPropertyIndexerExpression != null)
                    {
                        this.WritePropertyIndexerExpression(iPropertyIndexerExpression);
                    }
                    else
                    {
                        IDelegateCreateExpression iDelegateCreateExpression = expression as IDelegateCreateExpression;
                        if (iDelegateCreateExpression != null)
                        {
                            this.WriteDelegateCreateExpression(iDelegateCreateExpression);
                        }
                        else
                        {
                            ITypeOfExpression iTypeOfExpression = expression as ITypeOfExpression;
                            if (iTypeOfExpression != null)
                            {
                                this.WriteTypeOfExpression(iTypeOfExpression);
                            }
                            else
                            {
                                ISnippetExpression iSnippetExpression = expression as ISnippetExpression;
                                if (iSnippetExpression != null)
                                {
                                    this.WriteSnippetExpression(iSnippetExpression);
                                }
                                else
                                {
                                    IArrayIndexerExpression expression30 = expression as IArrayIndexerExpression;
                                    if (expression30 != null)
                                    {
                                        this.WriteArrayIndexerExpression(expression30);
                                    }
                                    else
                                    {
                                        IAddressDereferenceExpression expression29 = expression as IAddressDereferenceExpression;
                                        if (expression29 != null)
                                        {
                                            this.WriteAddressDereferenceExpression(expression29);
                                        }
                                        else
                                        {
                                            IAddressOfExpression expression28 = expression as IAddressOfExpression;
                                            if (expression28 != null)
                                            {
                                                this.WriteAddressOfExpression(expression28);
                                            }
                                            else
                                            {
                                                IAddressOutExpression expression27 = expression as IAddressOutExpression;
                                                if (expression27 != null)
                                                {
                                                    this.WriteAddressOutExpression(expression27);
                                                }
                                                else
                                                {
                                                    IAddressReferenceExpression expression26 = expression as IAddressReferenceExpression;
                                                    if (expression26 != null)
                                                    {
                                                        this.WriteAddressReferenceExpression(expression26);
                                                    }
                                                    else
                                                    {
                                                        IArgumentListExpression expression25 = expression as IArgumentListExpression;
                                                        if (expression25 != null)
                                                        {
                                                            this.WriteArgumentListExpression(expression25);
                                                        }
                                                        else
                                                        {
                                                            IUnaryExpression iUnaryExpression = expression as IUnaryExpression;
                                                            if (iUnaryExpression != null)
                                                            {
                                                                this.WriteUnaryExpression(iUnaryExpression);
                                                            }
                                                            else
                                                            {
                                                                IBinaryExpression iBinaryExpression = expression as IBinaryExpression;
                                                                if (iBinaryExpression != null)
                                                                {
                                                                    this.WriteBinaryExpression(iBinaryExpression);
                                                                }
                                                                else
                                                                {
                                                                    IBaseReferenceExpression iBaseReferenceExpression = expression as IBaseReferenceExpression;
                                                                    if (iBaseReferenceExpression != null)
                                                                    {
                                                                        this.WriteBaseReferenceExpression(iBaseReferenceExpression);
                                                                    }
                                                                    else
                                                                    {
                                                                        ITypeReferenceExpression iTypeReferenceExpression = expression as ITypeReferenceExpression;
                                                                        if (iTypeReferenceExpression != null)
                                                                        {
                                                                            this.WriteTypeReferenceExpression(iTypeReferenceExpression);
                                                                        }
                                                                        else
                                                                        {
                                                                            IObjectCreateExpression iObjectCreateExpression = expression as IObjectCreateExpression;
                                                                            if (iObjectCreateExpression != null)
                                                                            {
                                                                                this.WriteObjectCreateExpression(iObjectCreateExpression);
                                                                            }
                                                                            else
                                                                            {
                                                                                ICastExpression iCastExpression = expression as ICastExpression;
                                                                                if (iCastExpression != null)
                                                                                {
                                                                                    this.WriteCastExpression(iCastExpression);
                                                                                }
                                                                                else
                                                                                {
                                                                                    ILiteralExpression literalExpression = expression as ILiteralExpression;
                                                                                    if (literalExpression != null)
                                                                                    {
                                                                                        this.WriteLiteralExpression(literalExpression);
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                        IMethodInvokeExpression iMethodInvokeExpression = expression as IMethodInvokeExpression;
                                                                                        if (iMethodInvokeExpression != null)
                                                                                        {
                                                                                            this.WriteMethodInvokeExpression(iMethodInvokeExpression);
                                                                                        }
                                                                                        else
                                                                                        {
                                                                                            IMethodReferenceExpression iMethodReferenceExpression = expression as IMethodReferenceExpression;
                                                                                            if (iMethodReferenceExpression != null)
                                                                                            {
                                                                                                this.WriteMethodReferenceExpression(iMethodReferenceExpression);
                                                                                            }
                                                                                            else
                                                                                            {
                                                                                                IVariableDeclarationExpression expression15 = expression as IVariableDeclarationExpression;
                                                                                                if (expression15 != null)
                                                                                                {
                                                                                                    this.WriteVariableDeclaration(expression15.Variable);
                                                                                                }
                                                                                                else
                                                                                                {
                                                                                                    IVariableReferenceExpression iVariableReferenceExpression = expression as IVariableReferenceExpression;
                                                                                                    if (iVariableReferenceExpression != null)
                                                                                                    {
                                                                                                        this.WriteVariableReferenceExpression(iVariableReferenceExpression);
                                                                                                    }
                                                                                                    else
                                                                                                    {
                                                                                                        IArgumentReferenceExpression expression13 = expression as IArgumentReferenceExpression;
                                                                                                        if (expression13 != null)
                                                                                                        {
                                                                                                            this.WriteArgumentReferenceExpression(expression13);
                                                                                                        }
                                                                                                        else
                                                                                                        {
                                                                                                            IThisReferenceExpression expression12 = expression as IThisReferenceExpression;
                                                                                                            if (expression12 != null)
                                                                                                            {
                                                                                                                this.WriteThisReferenceExpression(expression12);
                                                                                                            }
                                                                                                            else
                                                                                                            {
                                                                                                                IPropertyReferenceExpression iPropertyReferenceExpression = expression as IPropertyReferenceExpression;
                                                                                                                if (iPropertyReferenceExpression != null)
                                                                                                                {
                                                                                                                    this.WritePropertyReferenceExpression(iPropertyReferenceExpression);
                                                                                                                }
                                                                                                                else
                                                                                                                {
                                                                                                                    IArrayCreateExpression expression10 = expression as IArrayCreateExpression;
                                                                                                                    if (expression10 != null)
                                                                                                                    {
                                                                                                                        this.WriteArrayCreateExpression(expression10);
                                                                                                                    }
                                                                                                                    else
                                                                                                                    {
                                                                                                                        IConditionExpression expression9 = expression as IConditionExpression;
                                                                                                                        if (expression9 != null)
                                                                                                                        {
                                                                                                                            this.WriteConditionExpression(expression9);
                                                                                                                        }
                                                                                                                        else
                                                                                                                        {
                                                                                                                            IFieldReferenceExpression iFieldReferenceExpression = expression as IFieldReferenceExpression;
                                                                                                                            if (iFieldReferenceExpression != null)
                                                                                                                            {
                                                                                                                                this.WriteFieldReferenceExpression(iFieldReferenceExpression);
                                                                                                                            }
                                                                                                                            else
                                                                                                                            {
                                                                                                                                ICanCastExpression iCanCastExpression = expression as ICanCastExpression;
                                                                                                                                if (iCanCastExpression != null)
                                                                                                                                {
                                                                                                                                    this.WriteCanCastExpression(iCanCastExpression);
                                                                                                                                }
                                                                                                                                else
                                                                                                                                {
                                                                                                                                    ITryCastExpression iTryCastExpression = expression as ITryCastExpression;
                                                                                                                                    if (iTryCastExpression != null)
                                                                                                                                    {
                                                                                                                                        this.WriteTryCastExpression(iTryCastExpression);
                                                                                                                                    }
                                                                                                                                    else
                                                                                                                                    {
                                                                                                                                        ICastExpression expression5 = expression as ICastExpression;
                                                                                                                                        if (expression5 != null)
                                                                                                                                        {
                                                                                                                                            this.WriteCastExpression(expression5);
                                                                                                                                        }
                                                                                                                                        else
                                                                                                                                        {
                                                                                                                                            IAssignExpression iAssignExpression = expression as IAssignExpression;
                                                                                                                                            if (iAssignExpression != null)
                                                                                                                                            {
                                                                                                                                                this.WriteAssignExpression(iAssignExpression);
                                                                                                                                            }
                                                                                                                                            else
                                                                                                                                            {
                                                                                                                                                IMemberInitializerExpression expression3 = expression as IMemberInitializerExpression;
                                                                                                                                                if (expression3 != null)
                                                                                                                                                {
                                                                                                                                                    this.WriteMemberInitializerExpression(expression3);
                                                                                                                                                }
                                                                                                                                                else
                                                                                                                                                {
                                                                                                                                                    IBlockExpression expression2 = expression as IBlockExpression;
                                                                                                                                                    if (expression2 != null)
                                                                                                                                                    {
                                                                                                                                                        this.WriteBlockExpression(expression2);
                                                                                                                                                    }
                                                                                                                                                    else
                                                                                                                                                    {
                                                                                                                                                        this.Write(expression.ToString());
                                                                                                                                                    }
                                                                                                                                                }
                                                                                                                                            }
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                }
                                                                                                                            }
                                                                                                                        }
                                                                                                                    }
                                                                                                                }
                                                                                                            }
                                                                                                        }
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            private void WriteExpressionCollection(IExpressionCollection iExpressionCollection)
            {
                string s = "";
                foreach (IExpression expression in iExpressionCollection)
                {
                    this.Write(s);
                    this.WriteExpression(expression);
                    s = ", ";
                }
            }

            private void WriteExpressionStatement(IExpressionStatement statement1)
            {
                this.WriteExpression(statement1.Expression);
                if (!this.SkipWriteLine)
                {
                    this.Write(";");
                    this.WriteLine();
                }
            }

            private void WriteExtendedStatement(IStatement statement)
            {
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                this.WriteStatement(statement);
                this.WriteOutdent();
                this.Write("}");
                this.WriteLine();
            }

            public virtual void WriteFieldDeclaration(IFieldDeclaration fieldDeclaration)
            {
                this.WriteFieldVisibilitySpecifier(fieldDeclaration.Visibility);
                if (fieldDeclaration.Literal)
                {
                    this.WriteKeyword("literal");
                    this.Write(" ");
                }
                else if (fieldDeclaration.Static)
                {
                    this.WriteKeyword("static");
                    this.Write(" ");
                }
                if (fieldDeclaration.ReadOnly)
                {
                    this.WriteKeyword("initonly");
                    this.Write(" ");
                }
                this.WriteType(fieldDeclaration.FieldType, new WriteTypeMiddleCallback(this.WriteName), fieldDeclaration.Name, null, false);
                IExpression initializer = fieldDeclaration.Initializer;
                if (initializer != null)
                {
                    this.Write(" = ");
                    this.WriteExpression(initializer);
                }
                this.Write(";");
            }

            private void WriteFieldReference(IFieldReference iFieldReference)
            {
                this.WriteReference(iFieldReference.Name, "", iFieldReference);
            }

            private void WriteFieldReferenceExpression(IFieldReferenceExpression iFieldReferenceExpression)
            {
                if (iFieldReferenceExpression.Target != null)
                {
                    ITypeReferenceExpression target = iFieldReferenceExpression.Target as ITypeReferenceExpression;
                    if (target != null)
                    {
                        this.WriteTypeReferenceExpression(target);
                        this.Write("::");
                    }
                    else
                    {
                        this.WriteExpression(iFieldReferenceExpression.Target);
                        IVariableReferenceExpression expression = iFieldReferenceExpression.Target as IVariableReferenceExpression;
                        if (expression != null)
                        {
                            IVariableReference variable = expression.Variable;
                            if (variable != null)
                            {
                                IVariableDeclaration declaration = variable.Resolve();
                                if (declaration != null)
                                {
                                    ITypeReference variableType = declaration.VariableType as ITypeReference;
                                    if (base.IsValueType(variableType))
                                    {
                                        this.Write(".");
                                    }
                                    else
                                    {
                                        this.Write("->");
                                    }
                                }
                            }
                        }
                        else
                        {
                            this.Write("->");
                        }
                    }
                }
                this.WriteFieldReference(iFieldReferenceExpression.Field);
            }

            private void WriteFieldVisibilitySpecifier(FieldVisibility visibility)
            {
                switch (visibility)
                {
                    case FieldVisibility.PrivateScope:
                        this.WriteKeyword("?PrivateScope?");
                        break;

                    case FieldVisibility.Private:
                        this.WriteKeyword("private");
                        break;

                    case FieldVisibility.FamilyAndAssembly:
                        this.WriteKeyword("private protected");
                        break;

                    case FieldVisibility.Assembly:
                        this.WriteKeyword("internal");
                        break;

                    case FieldVisibility.Family:
                        this.WriteKeyword("protected");
                        break;

                    case FieldVisibility.FamilyOrAssembly:
                        this.WriteKeyword("public protected");
                        break;

                    case FieldVisibility.Public:
                        this.WriteKeyword("public");
                        break;
                }
                this.Write(":");
                this.WriteLine();
            }

            private void WriteForEachStatement(IForEachStatement iForEachStatement)
            {
                this.WriteKeyword("for each");
                this.Write(" ");
                this.Write("(");
                this.WriteVariableDeclaration(iForEachStatement.Variable);
                this.Write(" ");
                this.WriteKeyword("in");
                this.Write(" ");
                this.SkipWriteLine = true;
                this.WriteExpression(iForEachStatement.Expression);
                this.SkipWriteLine = false;
                this.Write(")");
                this.WriteLine();
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                if (iForEachStatement.Body != null)
                {
                    this.WriteBlockStatement(iForEachStatement.Body);
                }
                this.WriteOutdent();
                this.Write("}");
                this.WriteLine();
            }

            private void WriteForStatement(IForStatement iForStatement)
            {
                this.WriteKeyword("for");
                this.Write(" ");
                this.Write("(");
                if (iForStatement.Initializer != null)
                {
                    this.SkipWriteLine = true;
                    this.WriteStatement(iForStatement.Initializer);
                    this.SkipWriteLine = false;
                    this.Write(" ");
                }
                this.Write("; ");
                if (iForStatement.Condition != null)
                {
                    this.SkipWriteLine = true;
                    this.WriteExpression(iForStatement.Condition);
                    this.SkipWriteLine = false;
                }
                this.Write("; ");
                if (iForStatement.Increment != null)
                {
                    this.SkipWriteLine = true;
                    this.WriteStatement(iForStatement.Increment);
                    this.SkipWriteLine = false;
                }
                this.Write(")");
                this.WriteLine();
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                if (iForStatement.Body != null)
                {
                    this.WriteStatement(iForStatement.Body);
                }
                this.WriteOutdent();
                this.Write("}");
                this.WriteLine();
            }

            private void WriteGenericArguments(ITypeCollection iTypeCollection)
            {
                if ((iTypeCollection != null) && (iTypeCollection.Count != 0))
                {
                    this.WriteKeyword("generic");
                    this.Write(" ");
                    string s = "<";
                    foreach (IType type in iTypeCollection)
                    {
                        this.Write(s);
                        this.WriteKeyword("typename");
                        this.Write(" ");
                        this.WriteType(type, null, null, null, false);
                        s = ", ";
                    }
                    this.Write(">");
                    this.WriteLine();
                }
            }

            private void WriteGenericParameterConstraintCollection(ITypeCollection parameters)
            {
                if (parameters.Count > 0)
                {
                    for (int i = 0; i < parameters.Count; i++)
                    {
                        IGenericParameter parameter = parameters[i] as IGenericParameter;
                        if ((parameter != null) && (parameter.Constraints.Count > 0))
                        {
                            bool flag = true;
                            if (parameter.Constraints.Count == 1)
                            {
                                ITypeReference reference = parameter.Constraints[0] as ITypeReference;
                                if (reference != null)
                                {
                                    flag = !base.IsObject(reference);
                                }
                            }
                            if (flag)
                            {
                                this.Write(" ");
                                this.WriteKeyword("where");
                                this.Write(" ");
                                this.Write(parameter.Name);
                                this.Write(":");
                                this.Write(" ");
                                string s = "";
                                for (int j = 0; j < parameter.Constraints.Count; j++)
                                {
                                    if (!(parameter.Constraints[j] is IDefaultConstructorConstraint))
                                    {
                                        this.Write(s);
                                        this.WriteType(parameter.Constraints[j], null, null, null, false);
                                        s = ", ";
                                    }
                                }
                            }
                        }
                        if (parameter.Attributes.Count > 0)
                        {
                            string str = "";
                            for (int k = 0; k < parameter.Attributes.Count; k++)
                            {
                                ICustomAttribute attribute = parameter.Attributes[k];
                                ITypeReference declaringType = attribute.Constructor.DeclaringType as ITypeReference;
                                ITypeReference reference2 = attribute.Constructor.DeclaringType as ITypeReference;
                                if (this.Type(attribute.Constructor.DeclaringType, "System->Runtime->CompilerServices", "NewConstraintAttribute"))
                                {
                                    this.Write(str);
                                    this.WriteKeyword("gcnew");
                                    this.Write("()");
                                    str = ", ";
                                }
                            }
                        }
                    }
                }
            }

            private void WriteGotoStatement(IGotoStatement iGotoStatement)
            {
                this.WriteKeyword("goto");
                this.Write(" ");
                this.WriteDeclaration(iGotoStatement.Name);
                this.Write(";");
                this.WriteLine();
            }

            private void WriteIndent()
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.WriteIndent();
                }
            }

            private void WriteKeyword(string s)
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.WriteKeyword(s);
                }
            }

            private void WriteLabeledStatement(ILabeledStatement iLabeledStatement)
            {
                this.WriteDeclaration(iLabeledStatement.Name);
                this.Write(":");
                this.WriteLine();
                if (iLabeledStatement.Statement != null)
                {
                    this.WriteStatement(iLabeledStatement.Statement);
                }
            }

            private void WriteLine()
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.WriteLine();
                }
            }

            private void WriteLiteral(string s)
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.WriteLiteral(s);
                }
            }

            private void WriteLiteralExpression(ILiteralExpression literalExpression)
            {
                object u = literalExpression.Value;
                if ( u is bool )
                {
                    string str4;
                    if ((bool) u)
                    {
                        str4 = "true";
                    }
                    else
                    {
                        str4 = "false";
                    }
                    this.WriteLiteral(str4);
                    return;
                }
                if ( u is char )
                {
                    this.Write("'");
                    this.WriteLiteral(((char) u).ToString(CultureInfo.InvariantCulture));
                    this.Write("'");
                    return;
                }
                if ( u is sbyte )
                {
                    sbyte num15 = (sbyte) u;
                    sbyte num30 = num15;
                    this.WriteLiteral(((sbyte) num30).ToString(CultureInfo.InvariantCulture));
                    return;
                }
                if ( u is byte )
                {
                    this.WriteLiteral(((byte) u).ToString(CultureInfo.InvariantCulture));
                    return;
                }
                if ( u is short )
                {
                    this.WriteLiteral(((short) u).ToString(CultureInfo.InvariantCulture));
                    return;
                }
                if ( u is  ushort )
                {
                    this.WriteLiteral(((ushort) u).ToString(CultureInfo.InvariantCulture));
                    return;
                }
                if ( u is int)
                {
                    int num4 = (int) u;
                    uint num6 = (uint) num4;
                    if ((num6 >= 0x80000000) && (num6 <= 0x8fffffff))
                    {
                        this.WriteLiteral("0x" + num4.ToString("X8"));
                    }
                    else
                    {
                        this.WriteLiteral(num4.ToString(CultureInfo.InvariantCulture));
                    }
                    return;
                }
                if (u is uint)
                {
                    uint num3 = (uint) u;
                    if (num3 >= 0x80000000)
                    {
                        this.WriteLiteral("0x" + num3.ToString("X8"));
                    }
                    else
                    {
                        this.WriteLiteral(num3.ToString(CultureInfo.InvariantCulture));
                    }
                    return;
                }
                if ( u is long )
                {
                    this.WriteLiteral(((long) u).ToString(CultureInfo.InvariantCulture));
                    return;
                }
                if ( u is ulong )
                {
                    this.WriteLiteral(((ulong) u).ToString(CultureInfo.InvariantCulture));
                    return;
                }
                if ( u is float )
                {
                    this.WriteLiteral(((float) u).ToString(CultureInfo.InvariantCulture) + "f");
                    return;
                }
                if ( u is double )
                {
                    this.WriteLiteral(((double) u).ToString(CultureInfo.InvariantCulture));
                    return;
                }
                if ( u is decimal )
                {
                    this.WriteLiteral(((decimal) u).ToString(CultureInfo.InvariantCulture));
                    return;
                }
                if (u == null)
                {
                    this.WriteLiteral("nullptr");
                    return;
                }
                string str3 = u as string;
                if (str3 == null)
                {
                    byte[] buffer = u as byte[];
                    if (buffer == null)
                    {
                        this.Write("Literal expression type NYI");
                        return;
                    }
                    string s = "{ ";
                    for (int i = 0; i < buffer.Length; i++)
                    {
                        this.Write(s);
                        this.WriteLiteral("0x" + buffer[i].ToString("X2"));
                        s = ",";
                    }
                    this.Write(" }");
                    return;
                }
                this.Write("\"");
                string str2 = str3;
                int num2 = 0;
            Label_030B:
                if (num2 >= str2.Length)
                {
                    this.Write("\"");
                }
                else
                {
                    char ch = str2[num2];
                    if (ch >= '\x0080')
                    {
                        this.WriteLiteral(@"\u" + ((uint) ch).ToString("X4"));
                    }
                    else
                    {
                        int num5 = ch;
                        if (num5 != 10)
                        {
                            if (num5 != 13)
                            {
                                this.WriteLiteral(ch.ToString(CultureInfo.InvariantCulture));
                            }
                            else
                            {
                                this.WriteLiteral(@"\r");
                            }
                        }
                        else
                        {
                            this.WriteLiteral(@"\n");
                        }
                    }
                    num2++;
                    goto Label_030B;
                }
            }

            private void WriteLockStatement(ILockStatement statement)
            {
                this.WriteKeyword("lock");
                this.Write(" ");
                this.Write("(");
                this.WriteExpression(statement.Expression);
                this.Write(")");
                this.WriteLine();
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                if (statement.Body != null)
                {
                    this.WriteBlockStatement(statement.Body);
                }
                this.WriteOutdent();
                this.Write("}");
                this.WriteLine();
            }

            private void WriteMemberInitializerExpression(IMemberInitializerExpression expression1)
            {
                this.WriteMemberReference(expression1.Member);
                this.Write("=");
                this.WriteExpression(expression1.Value);
            }

            private void WriteMemberReference(IMemberReference iMemberReference)
            {
                IFieldReference iFieldReference = iMemberReference as IFieldReference;
                if (iFieldReference != null)
                {
                    this.WriteFieldReference(iFieldReference);
                }
                else
                {
                    IMethodReference iMethodReference = iMemberReference as IMethodReference;
                    if (iMethodReference != null)
                    {
                        this.WriteMethodReference(iMethodReference);
                    }
                    else
                    {
                        IPropertyReference iPropertyReference = iMemberReference as IPropertyReference;
                        if (iPropertyReference != null)
                        {
                            this.WritePropertyReference(iPropertyReference);
                        }
                        else
                        {
                            IEventReference iEventReference = iMemberReference as IEventReference;
                            if (iEventReference != null)
                            {
                                this.WriteEventReference(iEventReference);
                            }
                            else
                            {
                                try
                                {
                                    this.Write(iMemberReference.ToString());
                                }
                                catch (Exception exception)
                                {
                                    this.Write(exception.ToString());
                                }
                            }
                        }
                    }
                }
            }

            private void WriteMethodBody(IBlockStatement statement)
            {
                if (((this.configuration["ShowMethodDeclarationBody"] == "true") && (statement != null)) && (statement != null))
                {
                    this.WriteStatement(statement);
                }
            }

            public virtual void WriteMethodDeclaration(IMethodDeclaration methodDeclaration)
            {
                bool flag2 = true;
                this.SkipTryCount = 0;
                this.SomeConstructor = false;
                this.refOnStack = new Hashtable();
                IConstructorDeclaration declaration2 = methodDeclaration as IConstructorDeclaration;
                ITypeDeclaration declaration = (methodDeclaration.DeclaringType as ITypeReference).Resolve();
                MethodNameExt ext = new MethodNameExt(methodDeclaration.Name, methodDeclaration.Overrides, declaration.Name);
                this.baseType = declaration.BaseType;
                bool flag = declaration.Name == "<Module>";
                if ((!flag && !declaration.Interface) && (!methodDeclaration.SpecialName || (methodDeclaration.Name != ".cctor")))
                {
                    this.WriteMethodVisibilitySpecifier(methodDeclaration.Visibility);
                    this.WriteLine();
                }
                this.WriteGenericArguments(declaration.GenericArguments);
                this.WriteGenericArguments(methodDeclaration.GenericArguments);
                if (!flag && methodDeclaration.Static)
                {
                    this.WriteKeyword("static");
                    this.Write(" ");
                }
                if (!declaration.Interface && methodDeclaration.Virtual)
                {
                    this.WriteKeyword("virtual");
                    this.Write(" ");
                }
                if ((this.configuration["ShowCustomAttributes"] == "true") && (methodDeclaration.Attributes.Count != 0))
                {
                    this.WriteCustomAttributeCollection(methodDeclaration, null);
                    this.WriteLine();
                }
                if (ext.Constructor || ext.StaticConstructor)
                {
                    this.SomeConstructor = true;
                    this.WriteMethodDeclMiddle(methodDeclaration);
                }
                else if (ext.ImplicitOrExplicit)
                {
                    if (ext.Explicit)
                    {
                        this.WriteKeyword("explicit");
                        this.Write(" ");
                    }
                    this.WriteKeyword("operator");
                    this.Write(" ");
                    this.WriteType(methodDeclaration.ReturnType.Type, null, null, null, false);
                    this.Write("(");
                    this.Write(")");
                }
                else
                {
                    this.WriteType(methodDeclaration.ReturnType.Type, new WriteTypeMiddleCallback(WriteMethodDeclMiddle), methodDeclaration, methodDeclaration.ReturnType, false);
                }
                if (!methodDeclaration.NewSlot && methodDeclaration.Final)
                {
                    this.Write(" ");
                    this.WriteKeyword("sealed");
                }
                if (methodDeclaration.Virtual)
                {
                    if (methodDeclaration.Abstract)
                    {
                        this.Write(" ");
                        this.WriteKeyword("abstract");
                    }
                    if (!methodDeclaration.NewSlot)
                    {
                        this.Write(" ");
                        this.WriteKeyword("override");
                    }
                }
                ICollection overrides = methodDeclaration.Overrides;
                if (overrides.Count > 0)
                {
                    string s = " = ";
                    foreach (IMethodReference reference in overrides)
                    {
                        this.Write(s);
                        this.WriteReference(reference.Name, "", reference);
                        s = ", ";
                    }
                }
                this.WriteGenericParameterConstraintCollection(methodDeclaration.GenericArguments);
                if (!ext.Constructor || (declaration2 == null))
                {
                    goto Label_05F5;
                }
                IMethodInvokeExpression initializer = declaration2.Initializer;
                if (initializer != null)
                {
                    IMethodReferenceExpression method = initializer.Method as IMethodReferenceExpression;
                    if ((method != null) && (initializer.Arguments.Count != 0))
                    {
                        this.Write(" : ");
                        this.WriteExpression(method.Target);
                        this.Write("(");
                        this.WriteExpressionCollection(initializer.Arguments);
                        this.Write(")");
                    }
                    goto Label_05F5;
                }
                IBlockStatement body = methodDeclaration.Body as IBlockStatement;
                if (body == null)
                {
                    goto Label_05F5;
                }
                IStatementCollection iStatementCollection = body.Statements;
                this.GatherExtraTemporaries(iStatementCollection);
                if (this.SkipNullptrCount >= iStatementCollection.Count)
                {
                    goto Label_05F5;
                }
                IStatement statement8 = iStatementCollection[this.SkipNullptrCount];
                ITryCatchFinallyStatement statement2 = statement8 as ITryCatchFinallyStatement;
                if ((statement2 == null) || (statement2.Try == null))
                {
                    goto Label_05F5;
                }
                IEnumerator enumerator = statement2.Try.Statements.GetEnumerator();
                {
                Label_03D3:
                    if (enumerator.MoveNext())
                    {
                        IStatement current = (IStatement) enumerator.Current;
                        IAssignExpression expression7 = current as IAssignExpression;
                        if (expression7 != null)
                        {
                            if (!(expression7.Target is IFieldReferenceExpression))
                            {
                                goto Label_04B8;
                            }
                            this.SkipTryCount++;
                            goto Label_03D3;
                        }
                        IExpressionStatement statement3 = current as IExpressionStatement;
                        if (statement3 != null)
                        {
                            if (statement3.Expression is IVariableDeclarationExpression)
                            {
                                this.SkipTryCount++;
                                goto Label_03D3;
                            }
                            IMethodInvokeExpression expression = statement3.Expression as IMethodInvokeExpression;
                            if (expression != null)
                            {
                                IMethodReferenceExpression expression5 = expression.Method as IMethodReferenceExpression;
                                if ((expression5 != null) && (expression5.Target is IBaseReferenceExpression))
                                {
                                    this.SkipTryCount++;
                                    goto Label_03D3;
                                }
                            }
                        }
                    }
                }
            Label_04B8:
                if (this.SkipTryCount != 0)
                {
                    flag2 = false;
                    this.WriteLine();
                    this.WriteIndent();
                    this.Write("try : ");
                    string str = "";
                    for (int i = 0; i < this.SkipTryCount; i++)
                    {
                        this.Write(str);
                        str = "";
                        IStatement statement5 = statement2.Try.Statements[i];
                        IAssignExpression expression3 = statement5 as IAssignExpression;
                        if (expression3 != null)
                        {
                            IFieldReferenceExpression target = expression3.Target as IFieldReferenceExpression;
                            this.Write(target.Field.Name);
                            this.Write("(");
                            this.WriteExpression(expression3.Expression);
                            this.Write(")");
                            str = ", ";
                        }
                        else
                        {
                            IExpressionStatement statement4 = statement5 as IExpressionStatement;
                            if (statement4 != null)
                            {
                                IMethodInvokeExpression expression2 = statement4.Expression as IMethodInvokeExpression;
                                if (expression2 != null)
                                {
                                    IMethodReferenceExpression expression4 = expression2.Method as IMethodReferenceExpression;
                                    if ((expression4 != null) && (expression4.Target is IBaseReferenceExpression))
                                    {
                                        this.WriteTypeReference(this.baseType);
                                        this.Write("(");
                                        this.WriteExpressionCollection(expression2.Arguments);
                                        this.Write(")");
                                        str = ", ";
                                    }
                                }
                            }
                        }
                    }
                }
            Label_05F5:
                this.WriteLine();
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                IBlockStatement statement = methodDeclaration.Body as IBlockStatement;
                if (statement != null)
                {
                    this.GatherExtraTemporaries(statement.Statements);
                    if (this.SkipNullptrCount != 0)
                    {
                        Save4ExtraPass pass = null;
                        Save4ExtraPass pass2 = new Save4ExtraPass(this);
                        try
                        {
                            pass = pass2;
                            this.NextBlock = 1;
                            this.Block = this.NextBlock;
                            this.NextBlock++;
                            this.WriteMethodBody(statement);
                        }
                        finally
                        {
                            pass.Dispose();
                        }
                        pass.Dispose();
                    }
                    this.WriteMethodBody(statement);
                }
                this.WriteOutdent();
                if (flag2)
                {
                    this.Write("}");
                }
                this.ExtraTemporaries = null;
            }

            private void WriteMethodDeclMiddle(object methodDecl)
            {
                IMethodDeclaration declaration = methodDecl as IMethodDeclaration;
                ITypeDeclaration declaration2 = (declaration.DeclaringType as ITypeReference).Resolve();
                MethodNameExt ext = new MethodNameExt(declaration.Name, declaration.Overrides, declaration2.Name);
                this.WriteDeclaration(ext.Name);
                this.WriteMethodParameterCollection(declaration.Parameters);
            }

            private void WriteMethodInvokeExpression(IMethodInvokeExpression iMethodInvokeExpression)
            {
                this.WriteExpression(iMethodInvokeExpression.Method);
                this.Write("(");
                this.WriteExpressionCollection(iMethodInvokeExpression.Arguments);
                this.Write(")");
            }

            private void WriteMethodParameterCollection(IParameterDeclarationCollection parameters)
            {
                this.Write("(");
                string s = "";
                foreach (IParameterDeclaration declaration in parameters)
                {
                    this.Write(s);
                    this.WriteType(declaration.ParameterType, new WriteTypeMiddleCallback(WriteName), declaration.Name, declaration, false);
                    s = ", ";
                }
                this.Write(")");
            }

            private void WriteMethodReference(IMethodReference iMethodReference)
            {
                MethodNameExt ext = new MethodNameExt(iMethodReference.Name, null, null);
                this.WriteReference(ext.Name, "", iMethodReference);
                ITypeCollection genericArguments = iMethodReference.GenericArguments;
                if (genericArguments.Count != 0)
                {
                    this.Write("<");
                    this.WriteTypeCollection(genericArguments);
                    this.Write(">");
                }
            }

            private void WriteMethodReferenceExpression(IMethodReferenceExpression iMethodReferenceExpression)
            {
                if (iMethodReferenceExpression.Target != null)
                {
                    ITypeReferenceExpression target = iMethodReferenceExpression.Target as ITypeReferenceExpression;
                    if (target != null)
                    {
                        this.WriteTypeReferenceExpression(target);
                        this.Write("::");
                    }
                    else
                    {
                        this.WriteExpression(iMethodReferenceExpression.Target);
                        IVariableReferenceExpression expression = iMethodReferenceExpression.Target as IVariableReferenceExpression;
                        if (expression != null)
                        {
                            IVariableReference variable = expression.Variable;
                            if (variable != null)
                            {
                                IVariableDeclaration declaration = variable.Resolve();
                                if (declaration != null)
                                {
                                    if (base.IsValueType(declaration.VariableType as ITypeReference) || this.refOnStack.Contains(this.MapTemporaryName(variable.ToString())))
                                    {
                                        this.Write(".");
                                    }
                                    else
                                    {
                                        this.Write("->");
                                    }
                                }
                            }
                        }
                        else
                        {
                            this.Write("->");
                        }
                    }
                }
                this.WriteMethodReference(iMethodReferenceExpression.Method);
            }

            private void WriteMethodReturnStatement(IMethodReturnStatement iMethodReturnStatement)
            {
                this.WriteKeyword("return");
                if (iMethodReturnStatement.Expression != null)
                {
                    this.Write(" ");
                    this.WriteExpression(iMethodReturnStatement.Expression);
                }
                this.Write(";");
                this.WriteLine();
            }

            private void WriteMethodVisibilitySpecifier(MethodVisibility visibility)
            {
                switch (visibility)
                {
                    case MethodVisibility.PrivateScope:
                        this.WriteKeyword("?PrivateScope?");
                        break;

                    case MethodVisibility.Private:
                        this.WriteKeyword("private");
                        break;

                    case MethodVisibility.FamilyAndAssembly:
                        this.WriteKeyword("private protected");
                        break;

                    case MethodVisibility.Assembly:
                        this.WriteKeyword("internal");
                        break;

                    case MethodVisibility.Family:
                        this.WriteKeyword("protected");
                        break;

                    case MethodVisibility.FamilyOrAssembly:
                        this.WriteKeyword("public protected");
                        break;

                    case MethodVisibility.Public:
                        this.WriteKeyword("public");
                        break;
                }
                this.Write(":");
            }

            private void WriteModifiedType(ITypeReference modifier, IType type, [MarshalAs(UnmanagedType.U1)] bool required, [MarshalAs(UnmanagedType.U1)] bool fRefOnStack)
            {
                if (this.Type(modifier, "System.Runtime.CompilerServices", "Volatile"))
                {
                    this.WriteKeyword("volatile");
                    this.Write(" ");
                    this.WriteType(type, null, null, null, fRefOnStack);
                }
                else if (this.Type(modifier, "System.Runtime.CompilerServices", "IsConst"))
                {
                    if (!fRefOnStack)
                    {
                        this.WriteKeyword("const");
                        this.Write(" ");
                    }
                    this.WriteType(type, null, null, null, fRefOnStack);
                }
                else if (this.Type(modifier, "System.Runtime.CompilerServices", "long"))
                {
                    this.WriteKeyword("long");
                }
                else
                {
                    string str;
                    this.WriteType(type, null, null, null, fRefOnStack);
                    this.Write(" ");
                    if (required)
                    {
                        str = "modreq";
                    }
                    else
                    {
                        str = "modopt";
                    }
                    this.WriteKeyword(str);
                    this.Write("(");
                    this.WriteType(modifier, null, null, null, false);
                    this.Write(")");
                }
            }

            public virtual void WriteModule(IModule module)
            {
                this.Write("// Module");
                this.Write(" ");
                this.WriteDeclaration(module.Name);
                this.WriteLine();
                if ((this.configuration["ShowCustomAttributes"] == "true") && (module.Attributes.Count != 0))
                {
                    this.WriteLine();
                    this.WriteLine();
                }
                this.WriteProperty("Version", module.Version.ToString());
                this.WriteProperty("Location", module.Location);
                string path = Environment.ExpandEnvironmentVariables(module.Location);
                if (File.Exists(path))
                {
                    FileStream stream = null;
                    FileStream stream2 = new FileStream(path, FileMode.Open, FileAccess.Read);
                    try
                    {
                        stream = stream2;
                        this.WriteProperty("Size", stream.Length + " Bytes");
                    }
                    finally
                    {
                        stream.Dispose();
                    }
                    stream.Dispose();
                }
            }

            public virtual void WriteModuleReference(IModuleReference moduleReference)
            {
                this.Write("// Module Reference");
                this.Write(" ");
                this.WriteDeclaration(moduleReference.Name);
                this.WriteLine();
            }

            private void WriteName(object name)
            {
                try
                {
                    if (name != null)
                    {
                        this.Write(name as string);
                    }
                }
                catch (Exception)
                {
                    this.Write("exception deanwi");
                }
            }

            public virtual void WriteNamespace(INamespace namespaceDeclaration)
            {
                if (!(this.configuration["ShowNamespaceBody"] == "true"))
                {
                    this.WriteKeyword("namespace");
                    this.Write(" ");
                    string s = namespaceDeclaration.Name.Replace(".", "::");
                    this.WriteDeclaration(s);
                }
                else
                {
                    char[] separator = new char[] { '.' };
                    string[] strArray2 = namespaceDeclaration.Name.Split(separator);
                    foreach (string str2 in strArray2)
                    {
                        this.WriteKeyword("namespace");
                        this.Write(" ");
                        this.WriteDeclaration(str2);
                        this.Write(" { ");
                    }
                    this.WriteLine();
                    this.WriteIndent();
                    ArrayList list = new ArrayList(0);
                    foreach (ITypeDeclaration declaration in namespaceDeclaration.Types)
                    {
                        if (base.IsVisible(declaration, this.configuration.Visibility))
                        {
                            list.Add(declaration);
                        }
                    }
                    if (this.configuration["SortAlphabetically"] == "true")
                    {
                        list.Sort();
                    }
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (i != 0)
                        {
                            this.WriteLine();
                        }
                        this.WriteTypeDeclaration((ITypeDeclaration) list[i]);
                    }
                    this.WriteOutdent();
                    for (int j = strArray2.Length; j > 0; j--)
                    {
                        this.Write("}");
                    }
                }
            }

            private void WriteObjectCreateExpression(IObjectCreateExpression iObjectCreateExpression)
            {
                ITypeReference declaringType = iObjectCreateExpression.Type as ITypeReference;
                //ITypeReference declaringType = iObjectCreateExpression.Constructor.DeclaringType as ITypeReference;

                if (declaringType != null)
                {
                    if (!base.IsValueType(declaringType))
                    {
                        this.Write("gcnew ");
                    }
                    this.WriteTypeReference(declaringType);
                }
                this.Write("(");
                this.WriteExpressionCollection(iObjectCreateExpression.Arguments);
                this.Write(") ");
            }

            private void WriteOutdent()
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.WriteOutdent();
                }
            }

            private void WriteProperty(string s, string t)
            {
                if (!this.SuppressOutput)
                {
                    this.formatter.WriteProperty(s, t);
                }
            }

            public virtual void WritePropertyDeclaration(IPropertyDeclaration propertyDeclaration)
            {
                this.WriteKeyword("property");
                this.Write(" ");
                this.WriteType(propertyDeclaration.DeclaringType, null, null, null, false);
                this.Write(" ");
                this.Write(propertyDeclaration.Name);
                IParameterDeclarationCollection parameters = propertyDeclaration.Parameters;
                if (parameters != null)
                {
                    this.WritePropertyIndices(parameters);
                }
                this.Write(";");
            }

            private void WritePropertyIndexerExpression(IPropertyIndexerExpression iPropertyIndexerExpression)
            {
                this.WritePropertyReferenceExpression(iPropertyIndexerExpression.Target);
                this.Write("[");
                this.WriteExpressionCollection(iPropertyIndexerExpression.Indices);
                this.Write("]");
            }

            private void WritePropertyIndices(IParameterDeclarationCollection parameters)
            {
                if (parameters.Count != 0)
                {
                    this.Write("[");
                    string s = "";
                    foreach (IParameterDeclaration declaration in parameters)
                    {
                        this.Write(s);
                        this.WriteType(declaration.ParameterType, null, null, null, false);
                        s = ", ";
                    }
                    this.Write("]");
                }
            }

            private void WritePropertyReference(IPropertyReference iPropertyReference)
            {
                this.Write(iPropertyReference.Name);
            }

            private void WritePropertyReferenceExpression(IPropertyReferenceExpression iPropertyReferenceExpression)
            {
                if (iPropertyReferenceExpression.Target != null)
                {
                    ITypeReferenceExpression target = iPropertyReferenceExpression.Target as ITypeReferenceExpression;
                    if (target != null)
                    {
                        this.WriteTypeReferenceExpression(target);
                        this.Write("::");
                    }
                    else
                    {
                        this.WriteExpression(iPropertyReferenceExpression.Target);
                        IVariableReferenceExpression expression = iPropertyReferenceExpression.Target as IVariableReferenceExpression;
                        if (expression != null)
                        {
                            IVariableReference variable = expression.Variable;
                            if (variable != null)
                            {
                                IVariableDeclaration declaration = variable.Resolve();
                                if (declaration != null)
                                {
                                    ITypeReference variableType = declaration.VariableType as ITypeReference;
                                    if (base.IsValueType(variableType))
                                    {
                                        this.Write(".");
                                    }
                                    else
                                    {
                                        this.Write("->");
                                    }
                                }
                            }
                        }
                        else
                        {
                            this.Write("->");
                        }
                    }
                }
                this.WritePropertyReference(iPropertyReferenceExpression.Property);
            }

            private void WriteReference(string s, string t, object o)
            {
                if (this.SuppressOutput)
                {
                    return;
                }
                string[] strArray2 = new string[] { "System::Runtime::InteropServices::", "System::" };
                int index = 0;
            Label_0029:
                if (index < strArray2.Length)
                {
                    string str = strArray2[index];
                    if (!s.StartsWith(str))
                    {
                        index++;
                        goto Label_0029;
                    }
                    s = s.Remove(0, str.Length);
                }
                this.formatter.WriteReference(s, t, o);
            }

            private void WriteRemoveEventStatement(IRemoveEventStatement iRemoveEventStatement)
            {
                this.WriteEventReferenceExpression(iRemoveEventStatement.Event);
                this.Write(" -= ");
                this.WriteExpression(iRemoveEventStatement.Listener);
                this.Write(";");
                this.WriteLine();
            }

            public virtual unsafe void WriteResource(IResource resource)
            {
                this.Write("// ");
                ResourceVisibility visibility = resource.Visibility;
                if (*(((int*) &visibility)) != 0)
                {
                    if (*(((int*) &visibility)) == 1)
                    {
                        this.WriteKeyword("private");
                    }
                }
                else
                {
                    this.WriteKeyword("public");
                }
                this.Write(" ");
                this.WriteKeyword("resource");
                this.Write(" ");
                this.WriteDeclaration(resource.Name);
                this.WriteLine();
                IEmbeddedResource resource3 = resource as IEmbeddedResource;
                if (resource3 != null)
                {
                    this.WriteProperty("Size", resource3.Value.Length.ToString() + " bytes");
                }
                IFileResource resource2 = resource as IFileResource;
                if (resource2 != null)
                {
                    this.WriteProperty("Location", resource2.Location);
                }
            }

            private void WriteSnippetExpression(ISnippetExpression iSnippetExpression)
            {
                this.Write("(ISnippetExpression NYI)");
            }

            public virtual void WriteStatement(IStatement statement)
            {
                try
                {
                    ILockStatement statement20 = statement as ILockStatement;
                    if (statement20 != null)
                    {
                        this.WriteLockStatement(statement20);
                    }
                    else
                    {
                        IBreakStatement iBreakStatement = statement as IBreakStatement;
                        if (iBreakStatement != null)
                        {
                            this.WriteBreakStatement(iBreakStatement);
                        }
                        else
                        {
                            IDoStatement iDoStatement = statement as IDoStatement;
                            if (iDoStatement != null)
                            {
                                this.WriteDoStatement(iDoStatement);
                            }
                            else
                            {
                                IGotoStatement iGotoStatement = statement as IGotoStatement;
                                if (iGotoStatement != null)
                                {
                                    this.WriteGotoStatement(iGotoStatement);
                                }
                                else
                                {
                                    ILabeledStatement iLabeledStatement = statement as ILabeledStatement;
                                    if (iLabeledStatement != null)
                                    {
                                        this.WriteLabeledStatement(iLabeledStatement);
                                    }
                                    else
                                    {
                                        IMethodReturnStatement iMethodReturnStatement = statement as IMethodReturnStatement;
                                        if (iMethodReturnStatement != null)
                                        {
                                            this.WriteMethodReturnStatement(iMethodReturnStatement);
                                        }
                                        else
                                        {
                                            IForStatement iForStatement = statement as IForStatement;
                                            if (iForStatement != null)
                                            {
                                                this.WriteForStatement(iForStatement);
                                            }
                                            else
                                            {
                                                IWhileStatement iWhileStatement = statement as IWhileStatement;
                                                if (iWhileStatement != null)
                                                {
                                                    this.WriteWhileStatement(iWhileStatement);
                                                }
                                                else
                                                {
                                                    IConditionStatement iConditionStatement = statement as IConditionStatement;
                                                    if (iConditionStatement != null)
                                                    {
                                                        this.WriteConditionStatement(iConditionStatement);
                                                    }
                                                    else
                                                    {
                                                        IBlockStatement blockStatement = statement as IBlockStatement;
                                                        if (blockStatement != null)
                                                        {
                                                            this.WriteBlockStatement(blockStatement);
                                                        }
                                                        else
                                                        {
                                                            IForEachStatement iForEachStatement = statement as IForEachStatement;
                                                            if (iForEachStatement != null)
                                                            {
                                                                this.WriteForEachStatement(iForEachStatement);
                                                            }
                                                            else
                                                            {
                                                                IThrowExceptionStatement iThrowExceptionStatement = statement as IThrowExceptionStatement;
                                                                if (iThrowExceptionStatement != null)
                                                                {
                                                                    this.WriteThrowExceptionStatement(iThrowExceptionStatement);
                                                                }
                                                                else
                                                                {
                                                                    ITryCatchFinallyStatement statement8 = statement as ITryCatchFinallyStatement;
                                                                    if (statement8 != null)
                                                                    {
                                                                        this.WriteTryCatchFinallyStatement(statement8);
                                                                    }
                                                                    else
                                                                    {
                                                                        IExpressionStatement statement7 = statement as IExpressionStatement;
                                                                        if (statement7 != null)
                                                                        {
                                                                            this.WriteExpressionStatement(statement7);
                                                                        }
                                                                        else
                                                                        {
                                                                            IAttachEventStatement iAttachEventStatement = statement as IAttachEventStatement;
                                                                            if (iAttachEventStatement != null)
                                                                            {
                                                                                this.WriteAttachEventStatement(iAttachEventStatement);
                                                                            }
                                                                            else
                                                                            {
                                                                                IRemoveEventStatement iRemoveEventStatement = statement as IRemoveEventStatement;
                                                                                if (iRemoveEventStatement != null)
                                                                                {
                                                                                    this.WriteRemoveEventStatement(iRemoveEventStatement);
                                                                                }
                                                                                else
                                                                                {
                                                                                    ISwitchStatement iSwitchStatement = statement as ISwitchStatement;
                                                                                    if (iSwitchStatement != null)
                                                                                    {
                                                                                        this.WriteSwitchStatement(iSwitchStatement);
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                        IContinueStatement iContinueStatement = statement as IContinueStatement;
                                                                                        if (iContinueStatement != null)
                                                                                        {
                                                                                            this.WriteContinueStatement(iContinueStatement);
                                                                                        }
                                                                                        else
                                                                                        {
                                                                                            IUsingStatement iUsingStatement = statement as IUsingStatement;
                                                                                            if (iUsingStatement != null)
                                                                                            {
                                                                                                this.WriteUsingStatement(iUsingStatement);
                                                                                            }
                                                                                            else
                                                                                            {
                                                                                                try
                                                                                                {
                                                                                                    this.Write(statement.ToString());
                                                                                                }
                                                                                                catch (Exception exception)
                                                                                                {
                                                                                                    this.Write(exception.ToString());
                                                                                                    this.Write(";");
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    this.SkipWriteLine = false;
                }
            }

            private void WriteStatementCollection(IStatementCollection statementCollection, int First)
            {
                int num = First;
                goto Label_000B;
            Label_0007:
                num++;
            Label_000B:
                if (num >= statementCollection.Count)
                {
                    return;
                }
                IStatement statement3 = statementCollection[num];
                if ((num + 2) < statementCollection.Count)
                {
                    IAssignExpression expression4 = statement3 as IAssignExpression;
                    if (expression4 != null)
                    {
                        ITryCatchFinallyStatement statement = statementCollection[num + 1] as ITryCatchFinallyStatement;
                        if (statement != null)
                        {
                            IExpressionStatement statement2 = statementCollection[num + 2] as IExpressionStatement;
                            if (statement2 != null)
                            {
                                IMethodInvokeExpression expression5 = statement2.Expression as IMethodInvokeExpression;
                                if (expression5 != null)
                                {
                                    IMethodReferenceExpression method = expression5.Method as IMethodReferenceExpression;
                                    if (method != null)
                                    {
                                        IMethodReference reference = method.Method;
                                        if (((reference != null) && (statement.Try != null)) && (statement.Try.Statements.Count > 0))
                                        {
                                            IAssignExpression expression2 = statement.Try.Statements[0] as IAssignExpression;
                                            if ((expression2 != null) && (reference.Name == "Dispose"))
                                            {
                                                string variableName = this.GetVariableName(expression4.Target);
                                                string str3 = this.GetVariableName(method.Target);
                                                string str2 = this.GetVariableName(expression2.Target);
                                                string str = this.GetVariableName(expression2.Expression);
                                                if ((variableName == str) && (str3 == str2))
                                                {
                                                    IVariableDeclarationExpression target = expression4.Target as IVariableDeclarationExpression;
                                                    if (target != null)
                                                    {
                                                        this.Write("{");
                                                        this.WriteLine();
                                                        this.WriteIndent();
                                                        if (!this.SuppressOutput)
                                                        {
                                                            this.NotAReference(target.Variable.Name);
                                                        }
                                                        this.WriteType(target.Variable.VariableType, null, null, null, true);
                                                        this.Write(" ");
                                                        this.Write(target.Variable.Name);
                                                        this.Write(";");
                                                        this.WriteLine();
                                                        this.WriteBlockStatement(statement.Try);
                                                        this.WriteOutdent();
                                                        this.Write("}");
                                                        this.WriteLine();
                                                        num++;
                                                        num++;
                                                        goto Label_0007;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                this.WriteStatement(statement3);
                goto Label_0007;
            }

            private void WriteSwitchCaseCondition(IExpression iConditionCase)
            {
                IBinaryExpression expression = iConditionCase as IBinaryExpression;
                if (expression != null)
                {
                    if (expression.Operator == BinaryOperator.BooleanOr)
                    {
                        this.WriteSwitchCaseCondition(expression.Left);
                        this.WriteSwitchCaseCondition(expression.Right);
                    }
                }
                else
                {
                    this.WriteKeyword("case");
                    this.Write(" ");
                    this.WriteExpression(iConditionCase);
                    this.Write(":");
                    this.WriteLine();
                }
            }

            private void WriteSwitchStatement(ISwitchStatement iSwitchStatement)
            {
                this.WriteKeyword("switch");
                this.Write(" (");
                this.WriteExpression(iSwitchStatement.Expression);
                this.Write(")");
                this.WriteLine();
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                foreach (ISwitchCase case3 in iSwitchStatement.Cases)
                {
                    IConditionCase @case = case3 as IConditionCase;
                    if (@case != null)
                    {
                        this.WriteSwitchCaseCondition(@case.Condition);
                        this.Write("{");
                        this.WriteLine();
                        this.WriteIndent();
                        if (@case.Body != null)
                        {
                            this.WriteStatement(@case.Body);
                        }
                        this.WriteOutdent();
                        this.Write("}");
                        this.WriteLine();
                    }
                    IDefaultCase case2 = case3 as IDefaultCase;
                    if (case2 != null)
                    {
                        this.WriteKeyword("default");
                        this.Write(":");
                        this.WriteLine();
                        this.Write("{");
                        this.WriteLine();
                        this.WriteIndent();
                        if (case2.Body != null)
                        {
                            this.WriteStatement(case2.Body);
                        }
                        this.WriteOutdent();
                        this.Write("}");
                        this.WriteLine();
                    }
                }
                this.WriteOutdent();
                this.Write("}");
                this.WriteLine();
            }

            private void WriteThisReferenceExpression(IThisReferenceExpression x )
            {
                this.WriteKeyword("this");
            }

            private void WriteThrowExceptionStatement(IThrowExceptionStatement iThrowExceptionStatement)
            {
                this.WriteKeyword("throw");
                if (iThrowExceptionStatement.Expression != null)
                {
                    this.Write(" ");
                    this.WriteExpression(iThrowExceptionStatement.Expression);
                }
                this.Write(";");
                this.WriteLine();
            }

            private void WriteTryCastExpression(ITryCastExpression iTryCastExpression)
            {
                this.WriteKeyword("dynamic_cast");
                this.Write("<");
                this.WriteType(iTryCastExpression.TargetType, null, null, null, false);
                this.Write(">");
                this.Write("(");
                this.WriteExpression(iTryCastExpression.Expression);
                this.Write(")");
            }

            private void WriteTryCatchFinallyStatement(ITryCatchFinallyStatement statement)
            {
                int skipTryCount = this.SkipTryCount;
                this.SkipTryCount = 0;
                if (statement.Try != null)
                {
                    bool flag = false;
                    IEnumerator enumerator2 = statement.CatchClauses.GetEnumerator();
                    {
                    Label_0029:
                        if (enumerator2.MoveNext())
                        {
                            ICatchClause current = (ICatchClause) enumerator2.Current;
                            if (current.Body.Statements.Count == 0)
                            {
                                goto Label_0029;
                            }
                            flag = true;
                        }
                    }
                    if (!flag && (statement.Finally.Statements.Count != 0))
                    {
                        flag = true;
                    }
                    if (!flag)
                    {
                        this.WriteBlockStatement(statement.Try);
                        if (skipTryCount != 0)
                        {
                            this.WriteOutdent();
                            this.Write("}");
                            this.WriteLine();
                        }
                        return;
                    }
                }
                if (skipTryCount == 0)
                {
                    this.WriteKeyword("try");
                    this.WriteLine();
                    this.Write("{");
                    this.WriteLine();
                    this.WriteIndent();
                }
                if (statement.Try == null)
                {
                    goto Label_01AC;
                }
                IStatementCollection statementCollection = statement.Try.Statements;
                if (statementCollection.Count <= 0)
                {
                    goto Label_01AC;
                }
                int num2 = 0;
                goto Label_011B;
            Label_0117:
                num2++;
            Label_011B:
                if (num2 < skipTryCount)
                {
                    IStatement statement2 = statementCollection[num2];
                    IAssignExpression expression3 = statement2 as IAssignExpression;
                    if (expression3 != null)
                    {
                        if (expression3.Target is IFieldReferenceExpression)
                        {
                            goto Label_0117;
                        }
                    }
                    else
                    {
                        IExpressionStatement statement4 = statement2 as IExpressionStatement;
                        if (statement4 != null)
                        {
                            IMethodInvokeExpression expression2 = statement4.Expression as IMethodInvokeExpression;
                            if (expression2 != null)
                            {
                                IMethodReferenceExpression method = expression2.Method as IMethodReferenceExpression;
                                if ((method != null) && (method.Target is IBaseReferenceExpression))
                                {
                                    goto Label_0117;
                                }
                            }
                        }
                    }
                    this.WriteStatement(statement2);
                    goto Label_0117;
                }
                this.WriteStatementCollection(statementCollection, skipTryCount);
            Label_01AC:
                this.WriteOutdent();
                this.Write("}");
                this.WriteLine();
                IEnumerator enumerator = statement.CatchClauses.GetEnumerator();
                {
                Label_01D0:
                    if (!enumerator.MoveNext())
                    {
                        goto Label_0380;
                    }
                    ICatchClause clause = (ICatchClause) enumerator.Current;
                    this.WriteKeyword("catch");
                    ITypeReference variableType = (ITypeReference) clause.Variable.VariableType;
                    bool flag3 = clause.Variable.ToString().Length == 0;
                    bool flag2 = base.IsObject(variableType);
                    if (!flag3 || !flag2)
                    {
                        this.Write(" ");
                        this.Write("(");
                        this.WriteType(clause.Variable.VariableType, new WriteTypeMiddleCallback(WriteName), clause.Variable.ToString(), null, false);
                        this.Write(")");
                    }
                    if (clause.Condition != null)
                    {
                        this.Write(" ");
                        this.WriteKeyword("when");
                        this.Write(" ");
                        this.Write("(");
                        this.WriteExpression(clause.Condition);
                        this.Write(")");
                    }
                    this.WriteLine();
                    this.Write("{");
                    this.WriteLine();
                    this.WriteIndent();
                    if (clause.Body == null)
                    {
                        goto Label_0345;
                    }
                    IStatementCollection statements = clause.Body.Statements;
                    int num = 0;
                    goto Label_0304;
                Label_0300:
                    num++;
                Label_0304:
                    if (num < statements.Count)
                    {
                        IStatement statement3 = statements[num];
                        if ((!this.SomeConstructor || ((num + 1) < statements.Count)) || !(statement3 is IThrowExceptionStatement))
                        {
                            this.WriteStatement(statement3);
                        }
                        goto Label_0300;
                    }
                Label_0345:
                    this.WriteOutdent();
                    this.Write("}");
                    this.WriteLine();
                    goto Label_01D0;
                }
            Label_0380:
                if ((statement.Fault != null) && (statement.Fault.Statements.Count > 0))
                {
                    this.WriteKeyword("fault");
                    this.WriteLine();
                    this.Write("{");
                    this.WriteLine();
                    this.WriteIndent();
                    if (statement.Fault != null)
                    {
                        this.WriteStatement(statement.Fault);
                    }
                    this.WriteOutdent();
                    this.Write("}");
                    this.WriteLine();
                }
                if ((statement.Finally != null) && (statement.Finally.Statements.Count > 0))
                {
                    this.WriteKeyword("finally");
                    this.WriteLine();
                    this.Write("{");
                    this.WriteLine();
                    this.WriteIndent();
                    if (statement.Finally != null)
                    {
                        this.WriteStatement(statement.Finally);
                    }
                    this.WriteOutdent();
                    this.Write("}");
                    this.WriteLine();
                }
            }

            public virtual void WriteType(IType type, WriteTypeMiddleCallback callback, object middle, ICustomAttributeProvider __unnamed003, [MarshalAs(UnmanagedType.U1)] bool fRefOnStack)
            {
                if ((this.configuration["ShowCustomAttributes"] == "true") && (__unnamed003 != null))
                {
                    this.WriteCustomAttributeCollection(__unnamed003, type);
                }
                ITypeReference typeReference = type as ITypeReference;
                if (typeReference != null)
                {
                    this.WriteTypeReference(typeReference);
                    if (!base.IsValueType(typeReference) && !fRefOnStack)
                    {
                        this.Write("^");
                    }
                }
                else
                {
                    IArrayType type2 = type as IArrayType;
                    if (type2 != null)
                    {
                        this.Write("array<");
                        this.WriteType(type2.ElementType, null, null, null, false);
                        if (type2.Dimensions.Count > 1)
                        {
                            this.Write(", " + type2.Dimensions.Count.ToString());
                        }
                        this.Write(">^");
                    }
                    else
                    {
                        IPointerType type4 = type as IPointerType;
                        if (type4 != null)
                        {
                            this.WriteType(type4.ElementType, null, null, null, false);
                            this.Write("*");
                        }
                        else
                        {
                            IReferenceType type3 = type as IReferenceType;
                            if (type3 != null)
                            {
                                this.WriteType(type3.ElementType, null, null, null, false);
                                this.Write("%");
                            }
                            else
                            {
                                IOptionalModifier modifier2 = type as IOptionalModifier;
                                if (modifier2 != null)
                                {
                                    this.WriteModifiedType(modifier2.Modifier, modifier2.ElementType, false, fRefOnStack);
                                }
                                else
                                {
                                    IRequiredModifier modifier = type as IRequiredModifier;
                                    if (modifier != null)
                                    {
                                        this.WriteModifiedType(modifier.Modifier, modifier.ElementType, true, fRefOnStack);
                                    }
                                    else if (type is IFunctionPointer)
                                    {
                                        this.Write("funcptr");
                                    }
                                    else
                                    {
                                        IGenericParameter parameter = type as IGenericParameter;
                                        if (parameter != null)
                                        {
                                            this.Write(parameter.Name);
                                        }
                                        else
                                        {
                                            IGenericArgument argument = type as IGenericArgument;
                                            if (argument != null)
                                            {
                                                this.WriteType(argument.Resolve(), null, null, null, false);
                                            }
                                            else if (type is IValueTypeConstraint)
                                            {
                                                this.WriteKeyword("value");
                                                this.WriteKeyword(" ");
                                                this.WriteKeyword("class");
                                            }
                                            else if (!(type is IDefaultConstructorConstraint))
                                            {
                                                this.Write("WHAT TYPE IS IT?");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (callback != null)
                {
                    this.Write(" ");
                    callback(middle);
                }
            }

            private void WriteTypeCollection(ITypeCollection iTypeCollection)
            {
                string s = "";
                foreach (IType type in iTypeCollection)
                {
                    this.Write(s);
                    this.WriteType(type, null, null, null, false);
                    s = ", ";
                }
            }

            public virtual void WriteTypeDeclaration(ITypeDeclaration typeDeclaration)
            {
                if ((this.configuration["ShowCustomAttributes"] == "true") && (typeDeclaration.Attributes.Count != 0))
                {
                    this.WriteCustomAttributeCollection(typeDeclaration, null);
                    this.WriteLine();
                }
                if (base.IsDelegate(typeDeclaration))
                {
                    this.WriteDelegateDeclaration(typeDeclaration);
                }
                else if (base.IsEnumeration(typeDeclaration))
                {
                    this.WriteEnumDeclaration(typeDeclaration);
                }
                else
                {
                    this.WriteClassDeclaration(typeDeclaration);
                }
            }

            private void WriteTypeOfExpression(ITypeOfExpression iTypeOfExpression)
            {
                this.WriteType(iTypeOfExpression.Type, null, null, null, false);
                this.Write("::");
                this.WriteKeyword("typeid");
            }

            private void WriteTypeReference(ITypeReference typeReference)
            {
                string nameFromTypeReference = this.GetNameFromTypeReference(typeReference);
                string t = (typeReference.Namespace + "." + typeReference.Name).Replace(".", "::").Replace("+", "::");
                this.WriteReference(nameFromTypeReference, t, typeReference);
            }

            private void WriteTypeReferenceExpression(ITypeReferenceExpression iTypeReferenceExpression)
            {
                if (!(iTypeReferenceExpression.Type.Name == "UnmanagedType") && !(iTypeReferenceExpression.Type.Name == "<Module>"))
                {
                    this.WriteTypeReference(iTypeReferenceExpression.Type);
                }
            }

            private void WriteTypeVisibilitySpecifier(TypeVisibility visibility)
            {
                bool flag = true;
                switch (visibility)
                {
                    case TypeVisibility.Private:
                        flag = false;
                        goto Label_0042;

                    case TypeVisibility.Public:
                        flag = false;
                        break;

                    case TypeVisibility.NestedPublic:
                        break;

                    case TypeVisibility.NestedPrivate:
                        goto Label_0042;

                    case TypeVisibility.NestedFamily:
                        this.WriteKeyword("protected");
                        goto Label_00AD;

                    case TypeVisibility.NestedAssembly:
                        this.WriteKeyword("internal");
                        goto Label_00AD;

                    case TypeVisibility.NestedFamilyAndAssembly:
                        this.WriteKeyword("protected");
                        this.Write(" ");
                        this.WriteKeyword("private");
                        goto Label_00AD;

                    case TypeVisibility.NestedFamilyOrAssembly:
                        this.WriteKeyword("protected");
                        this.Write(" ");
                        this.WriteKeyword("public");
                        goto Label_00AD;

                    default:
                        goto Label_00AD;
                }
                this.WriteKeyword("public");
                goto Label_00AD;
            Label_0042:
                this.WriteKeyword("private");
            Label_00AD:
                if (flag)
                {
                    this.Write(":");
                    this.WriteLine();
                }
                else
                {
                    this.Write(" ");
                }
            }

            private void WriteUnaryExpression(IUnaryExpression iUnaryExpression)
            {
                switch (iUnaryExpression.Operator)
                {
                    case UnaryOperator.Negate:
                        this.Write("-");
                        this.WriteExpression(iUnaryExpression.Expression);
                        break;

                    case UnaryOperator.BooleanNot:
                        this.Write("!");
                        this.WriteExpression(iUnaryExpression.Expression);
                        break;

                    case UnaryOperator.BitwiseNot:
                        this.Write("~");
                        this.WriteExpression(iUnaryExpression.Expression);
                        break;

                    case UnaryOperator.PreIncrement:
                        this.Write("++");
                        this.WriteExpression(iUnaryExpression.Expression);
                        break;

                    case UnaryOperator.PreDecrement:
                        this.Write("--");
                        this.WriteExpression(iUnaryExpression.Expression);
                        break;

                    case UnaryOperator.PostIncrement:
                        this.WriteExpression(iUnaryExpression.Expression);
                        this.Write("++");
                        break;

                    case UnaryOperator.PostDecrement:
                        this.WriteExpression(iUnaryExpression.Expression);
                        this.Write("--");
                        break;

                    default:
                        throw new NotSupportedException(iUnaryExpression.Operator.ToString());
                }
            }

            private void WriteUsingStatement(IUsingStatement iUsingStatement)
            {
            }

            private void WriteVariableDeclaration(IVariableDeclaration iVariableDeclaration)
            {
                this.WriteType(iVariableDeclaration.VariableType, new WriteTypeMiddleCallback(WriteName), iVariableDeclaration.Name, null, false);
            }

            private void WriteVariableReferenceExpression(IVariableReferenceExpression iVariableReferenceExpression)
            {
                string t = "";
                object o = iVariableReferenceExpression;
                if (this.MapTemporaryName(iVariableReferenceExpression.Variable.Resolve().Name) != iVariableReferenceExpression.Variable.Resolve().Name)
                {
                    o = null;
                }
                this.WriteReference(this.MapTemporaryName(iVariableReferenceExpression.Variable.Resolve().Name), t, o);
            }

            private void WriteWhileStatement(IWhileStatement iWhileStatement)
            {
                this.WriteKeyword("while");
                this.Write(" ");
                this.Write("(");
                if (iWhileStatement.Condition != null)
                {
                    this.SkipWriteLine = true;
                    this.WriteExpression(iWhileStatement.Condition);
                    this.SkipWriteLine = false;
                }
                this.Write(")");
                this.WriteLine();
                this.Write("{");
                this.WriteLine();
                this.WriteIndent();
                if (iWhileStatement.Body != null)
                {
                    this.WriteStatement(iWhileStatement.Body);
                }
                this.WriteOutdent();
                this.Write("}");
                this.WriteLine();
            }

            private class DelegateDeclMiddleInfo
            {
                private ITypeDeclaration var_delegateDecl;
                private IMethodDeclaration var_invokeDecl;

                internal DelegateDeclMiddleInfo(ITypeDeclaration delegateDecl_, IMethodDeclaration invokeDecl_)
                {
                    this.var_delegateDecl = delegateDecl_;
                    this.var_invokeDecl = invokeDecl_;
                }

                internal ITypeDeclaration delegateDecl
                {
                    get
                    {
                        return this.var_delegateDecl;
                    }
                    set
                    {
                        this.var_delegateDecl = value;
                    }
                }

                internal IMethodDeclaration invokeDecl
                {
                    get
                    {
                        return this.var_invokeDecl;
                    }
                    set
                    {
                        this.var_invokeDecl = value;
                    }
                }
            }

            public class NewBlock : IDisposable
            {
                public int Block;
                public CppCliLanguage.LanguageWriter m_r;

                public NewBlock(CppCliLanguage.LanguageWriter r)
                {
                    this.m_r = r;
                    this.Block = this.m_r.Block;
                    this.m_r.Block = this.m_r.NextBlock;
                    this.m_r.NextBlock++;
                }

                void Destruct()
                {
                    this.m_r.Block = this.Block;
                }

                ~NewBlock()
                {
                    Destruct();
                }

                public void Dispose()
                {     
                    this.Dispose(true);
                    GC.SuppressFinalize(this);
                }

                protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1)
                {
                    if (flag1)
                    {
                        this.Destruct();
                    }
                    //else
                    //{
                        //base.Dispose();
                    //}
                }
            }

            public class Save4ExtraPass : IDisposable
            {
                public CppCliLanguage.LanguageWriter m_r;
                public int SkipTryCount;

                public Save4ExtraPass(CppCliLanguage.LanguageWriter r)
                {
                    this.m_r = r;
                    this.m_r.SuppressOutput = true;
                    this.SkipTryCount = this.m_r.SkipTryCount;
                }

                void Destruct()
                {
                    this.m_r.SuppressOutput = false;
                    this.m_r.SkipTryCount = this.SkipTryCount;
                    this.m_r.ExtraMappings = new string[this.m_r.SkipNullptrCount];
                }

                ~Save4ExtraPass()
                {
                    Destruct();
                }

                public void Dispose()
                {
                    this.Dispose(true);
                    GC.SuppressFinalize(this);
                }

                protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1)
                {
                    if (flag1)
                    {
                        Destruct();
                    }
                    //else
                    //{
                    //    base.Finalize();
                    //}
                }
            }

            public delegate void WriteTypeMiddleCallback(object middle);
        }
    }
}
